努力将令牌移动到2D阵列。 我的想法是我正在读取一个包含多行的文件,获取行数然后根据它创建一个2D数组以明智地使用内存(我不想无缘无故地创建一个100 x 3数组)。
我想我在单独的功能中初始化了2D数组但是当我尝试输入从strtok()读取的数据时,我收到错误:
error: 'arr' undeclared (first use in this function)
strcpy(&arr[s2][c2],token);
这是我的代码:
#include <stdio.h>
#include <string.h>
int ch, lines;
int no_of_lines(char* fp)
{
while(!feof(fp)) {
ch = fgetc(fp);
if(ch == '\n') {
lines++;
}
}
lines++;
return lines;
}
void declare_space_array(int size)
{
char* arr = (char*)malloc(size * 3 * sizeof(char));
return;
}
int main(void)
{
int c2 = 0;
int s2 = 0;
int len;
// char data[10][4];
static const char filename[] = "C:\\Users\\PC\\Documents\\Assignments\\stringops\\test.txt";
FILE* file = fopen(filename, "r");
no_of_lines(file);
printf("No of lines in file = %d", lines);
printf("\n");
// Closing file because it was read once till the end of file
fclose(file);
// Opening file again to read for parsing
file = fopen(filename, "r");
declare_space_array(lines);
char* token;
if(file != NULL) {
char line[128];
while(fgets(line, sizeof line, file) != NULL)
{
len = strlen(line);
printf("%d %s", len - 1, line);
const char s = ",";
token = strtok(line, ",");
while(token != NULL) {
strcpy(arr[s2][c2], token);
// printf( "%s\n", token );
token = strtok(NULL, ",");
c2++;
}
s2++;
}
fclose(file);
} else {
perror(filename); /* why didn't the file open? */
}
for(r1 = 0; r1 < lines; r1++) {
for(c1 = 0; c1 < 3; c1++) {
printf("%s", &arr[r1][c1]);
}
}
return 0;
}
文件是这样的:
A1,B1,C1
A2,B2,C2
A3,B3,C3
期望输出到这样的东西:
A1
B1
C1
A2
B2
C2
A3
B3
C3
答案 0 :(得分:1)
在聊天等讨论后,你可能会得到这样的代码。这使用全局变量arr
,它是指向3 char *
个值的数组数组的指针。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int lines = 0;
static char *(*arr)[3] = 0; // global definition.
static int no_of_lines(FILE *fp)
{
lines = 0;
int ch;
while ((ch = fgetc(fp)) != EOF)
{
if (ch == '\n')
lines++;
}
return ++lines; // Allow for last line possibly not having a newline
}
static void declare_space_array(int size)
{
arr = calloc(size, 3 * sizeof(char *)); // zeroed memory allocation
if (arr == 0)
{
fprintf(stderr, "Failed to allocate memory\n");
exit(1);
}
}
int main(void)
{
int c2 = 0;
int s2 = 0;
int len;
// char data[10][4];
// static const char filename[] = "C:\\Users\\PC\\Documents\\Assignments\\stringops\\test.txt";
const char *filename = "data";
FILE *file = fopen(filename, "r");
if (file == 0)
{
fprintf(stderr, "Failed to open file '%s' for reading\n", filename);
exit(1);
}
no_of_lines(file);
printf("No of lines in file = %d\n", lines);
rewind(file);
declare_space_array(lines);
const char delims[] = ",\n";
char line[128];
while (fgets(line, sizeof line, file) != NULL)
{
char *token;
c2 = 0;
len = strlen(line);
printf("%d [%.*s]\n", len - 1, len - 1, line);
token = strtok(line, delims);
while (token != NULL)
{
arr[s2][c2] = strdup(token); // copy token (from strtok) into newly allocated string.
token = strtok(NULL, delims);
c2++;
}
s2++;
}
fclose(file);
for (int r1 = 0; r1 < lines; r1++)
{
if (arr[r1][0] != 0)
{
for (int c1 = 0; c1 < 3; c1++)
printf(" %-10s", arr[r1][c1]);
putchar('\n');
}
}
return 0;
}
它没有释放分配的内存 - 我很懒。
示例数据(请注意,名称长度超过2个字符且长度可变):
server1,Phoenix,Windows
server2,Dallas,Linux
server-99,London,z/OS
示例输出:
No of lines in file = 4
23 [server1,Phoenix,Windows]
20 [server2,Dallas,Linux]
21 [server-99,London,z/OS]
server1 Phoenix Windows
server2 Dallas Linux
server-99 London z/OS
file = 4&#39;中的行数允许在最后一行的末尾没有换行符。打印循环中的代码允许最后有换行符的可能性,因此计数是高估的。只要失败在一行的第一个字段上,它就会从strdup()
发现内存分配。如果它是未成功复制的第二个或第三个字段,它可能会崩溃。