gpt4 book ai didi

在文件 (C) 中找到行中的关键字后连接行

转载 作者:太空宇宙 更新时间:2023-11-04 08:22:00 25 4
gpt4 key购买 nike

我有一个看起来像这样的文本文件:

pickupInterval 30.0
.
.
map
0 3 -1 -1 -1 2
3 0 5 -1 -1 -1
-1 -1 0 2 -1 -1
-1 -1 -1 0 2 3
-1 1 -1 -1 0 -1
4 -1 -1 8 1 0

而且我无法找到读取矩阵的方法(大小未知,但为 NxN)。到目前为止,这是我的代码:

//other irrelevant code here
while (fgets(buffer, sizeof buffer, fp) != NULL)
{
sscanf(buffer, "%s", var);
.
.
//looking for known keywords
.
.
if (strcmp(var,"pickupInterval") == 0)
{
sscanf(buffer, "%s %f",var,&pickupInterval);
}
.
.
.
if (strcmp(var,"map") == 0)
{
/* map keyword detected
* read next line
* find the size of N (ie. NxN matrix)
* read next N-1 lines and make matrix out of them (I know how to loop, I don't know how to "read next N-1 lines" part would look like)
*/
}
}
//other irrelevant code here

它逐行进行,如果检测到关键字,它会将值分配给全局变量。但是,如果检测到关键字 MAP,我不知道如何继续。

一个想法是在找到 N 之后简单地连接所有 N-1 行(+ Map 关键字之后的行),然后从中创建矩阵。但是,我再次陷入了“读取下 N-1 行”部分,甚至是“找到 map 后读取行”部分的阶段。

最佳答案

用 C 从文件中读取未知数量的 和未知数量的 没有什么困难,但你必须特别注意你是如何做到的.当您将数组限制为正方形 (NxN) 数组时,没有理由每行不能有不同数量的列(它称为 锯齿状数组) .

您的基本方法是为一个指针数组分配内存,以键入int,以获得一些合理的预期行数。然后您将阅读每一行。然后,对于您阅读的每一行,您都会为一些合理预期的整数数量的“int”数组分配一 block 内存。

然后,您将遇到的每个数字串转换为一个整数值,并将该数字存储在 array[row][col] 中。 (我们实际上开始在 col = 1 处存储值并保存 col = 0 以保存该行的最终 cols 数)你跟踪你拥有的整数数添加到数组中,如果您的列数达到您分配的数量,则您可以为该行重新分配该数组(例如array[row])以保存额外的整数。

您继续阅读行,直到阅读完所有行。如果您达到了原始行数限制,您只需重新分配指针数组(例如array),就像您使用达到限制时所做的那样cols.

您现在已经存储了所有数据,可以随心所欲地使用它。完成后,不要忘记释放您分配的所有内存。我整理了一个小例子来说明。此示例不需要方阵,并且可以愉快地每行存储任意数量的整数。我没有包括文件打开/文件读取代码,而是简单地让示例从 stdin 读取数据。

为了保持代码主体的整洁以便于阅读,转换、分配和重新分配代码包含在函数中(xstrtolxcallocxrealloc_sp(单指针)和xrealloc_dp(双指针))。如果您有任何问题,请告诉我:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>

#define ROWS 100
#define COLS 16
#define MAXC 256

long xstrtol (char *p, char **ep, int base);
void *xcalloc (size_t n, size_t s);
void *xrealloc_sp (void *p, size_t sz, size_t *n);
void *xrealloc_dp (void **p, size_t *n);

int main (void) {

char line[MAXC] = {0}; /* line buffer for fgets */
char *p, *ep; /* pointers for strtol */
int **array = NULL; /* array of values */
size_t row = 0, col = 0, nrows = 0; /* indexes, number of rows */
size_t rmax = ROWS, cmax = COLS; /* row/col allocation size */

/* allocate ROWS number of pointers to array of int */
array = xcalloc (ROWS, sizeof *array);

/* read each line in file */
while (fgets(line, MAXC, stdin))
{
p = ep = line; /* initize pointer/end pointer */
col = 1; /* start col at 1, num cols stored at 0 */
cmax = COLS; /* reset cmax for each row */

/* allocate COLS number of int for each row */
array[row] = xcalloc (COLS, sizeof **array);

/* convert each string of digits to number */
while (errno == 0)
{
array[row][col++] = (int)xstrtol (p, &ep, 10);

if (col == cmax) /* if cmax reached, realloc array[row] */
array[row] = xrealloc_sp (array[row], sizeof *array[row], &cmax);

/* skip delimiters/move pointer to next digit */
while (*ep && *ep != '-' && (*ep < '0' || *ep > '9')) ep++;
if (*ep)
p = ep;
else /* break if end of string */
break;
}
array[row++][0] = col; /* store ncols in array[row][0] */

/* realloc rows if needed */
if (row == rmax) array = xrealloc_dp ((void **)array, &rmax);
}
nrows = row; /* set nrows to final number of rows */

printf ("\n the simulated 2D array elements are:\n\n");
for (row = 0; row < nrows; row++) {
for (col = 1; col < (size_t)array[row][0]; col++)
printf (" %4d", array[row][col]);
putchar ('\n');
}
putchar ('\n');

/* free all allocated memory */
for (row = 0; row < nrows; row++)
free (array[row]);
free (array);

return 0;
}

/** a simple strtol implementation with error checking.
* any failed conversion will cause program exit. Adjust
* response to failed conversion as required.
*/
long xstrtol (char *p, char **ep, int base)
{
errno = 0;

long tmp = strtol (p, ep, base);

/* Check for various possible errors */
if ((errno == ERANGE && (tmp == LONG_MIN || tmp == LONG_MAX)) ||
(errno != 0 && tmp == 0)) {
perror ("strtol");
exit (EXIT_FAILURE);
}

if (*ep == p) {
fprintf (stderr, "No digits were found\n");
exit (EXIT_FAILURE);
}

return tmp;
}

/** xcalloc allocates memory using calloc and validates the return.
* xcalloc allocates memory and reports an error if the value is
* null, returning a memory address only if the value is nonzero
* freeing the caller of validating within the body of code.
*/
void *xcalloc (size_t n, size_t s)
{
register void *memptr = calloc (n, s);
if (memptr == 0)
{
fprintf (stderr, "%s() error: virtual memory exhausted.\n", __func__);
exit (EXIT_FAILURE);
}

return memptr;
}

/** reallocate array of type size 'sz', to 2 * 'n'.
* accepts any pointer p, with current allocation 'n',
* with the type size 'sz' and reallocates memory to
* 2 * 'n', updating the value of 'n' and returning a
* pointer to the newly allocated block of memory on
* success, exits otherwise. all new memory is
* initialized to '0' with memset.
*/
void *xrealloc_sp (void *p, size_t sz, size_t *n)
{
void *tmp = realloc (p, 2 * *n * sz);
#ifdef DEBUG
printf ("\n reallocating %zu to %zu\n", *n, *n * 2);
#endif
if (!tmp) {
fprintf (stderr, "%s() error: virtual memory exhausted.\n", __func__);
exit (EXIT_FAILURE);
}
p = tmp;
memset (p + *n * sz, 0, *n * sz); /* zero new memory */
*n *= 2;

return p;
}

/** reallocate memory for array of pointers to 2 * 'n'.
* accepts any pointer 'p', with current allocation of,
* 'n' pointers and reallocates to 2 * 'n' pointers
* intializing the new pointers to NULL and returning
* a pointer to the newly allocated block of memory on
* success, exits otherwise.
*/
void *xrealloc_dp (void **p, size_t *n)
{
void *tmp = realloc (p, 2 * *n * sizeof tmp);
#ifdef DEBUG
printf ("\n reallocating %zu to %zu\n", *n, *n * 2);
#endif
if (!tmp) {
fprintf (stderr, "%s() error: virtual memory exhausted.\n", __func__);
exit (EXIT_FAILURE);
}
p = tmp;
memset (p + *n, 0, *n * sizeof tmp); /* set new pointers NULL */
*n *= 2;

return p;
}

编译

gcc -Wall -Wextra -Ofast -o bin/array_ukn_size array_ukn_size.c

输入

$ cat array.txt
0 3 -1 -1 -1 2
3 0 5 -1 -1 -1
-1 -1 0 2 -1 -1
-1 -1 -1 0 2 3
-1 1 -1 -1 0 -1
4 -1 -1 8 1 0

使用/输出

$ ./bin/array_ukn_size <array.txt

the simulated 2D array elements are:

0 3 -1 -1 -1 2
3 0 5 -1 -1 -1
-1 -1 0 2 -1 -1
-1 -1 -1 0 2 3
-1 1 -1 -1 0 -1
4 -1 -1 8 1 0

内存检查

在您编写的任何动态分配内存的代码中,您都必须使用内存错误检查程序。对于 Linux,valgrind 是正常的选择。有许多微妙的方法可以滥用内存块,从而导致真正的问题,没有理由不这样做。每个平台都有类似的内存检查器。它们使用简单。只需通过它运行您的程序即可。

$ valgrind ./bin/array_ukn_size <array.txt
==14043== Memcheck, a memory error detector
==14043== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==14043== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==14043== Command: ./bin/array_ukn_size
==14043==

the simulated 2D array elements are:

0 3 -1 -1 -1 2
<snip>

==14043==
==14043== HEAP SUMMARY:
==14043== in use at exit: 0 bytes in 0 blocks
==14043== total heap usage: 7 allocs, 7 frees, 1,184 bytes allocated
==14043==
==14043== All heap blocks were freed -- no leaks are possible
==14043==
==14043== For counts of detected and suppressed errors, rerun with: -v
==14043== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

关于在文件 (C) 中找到行中的关键字后连接行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33045426/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com