我是C的新手(我一直在学习Cuda并且想学习C所以我可以一起运行所有内容而不是在Java / Python中生成数据并手动将其复制/粘贴到我的Cuda程序中)。我正在尝试打开一个大文件(20 + gb)并解析一些数据,但因为我遇到了问题,我决定先尝试分解我的问题以验证我可以逐行打开并逐行读取文件然后在另一个文件中获取一行的输出样本并尝试解析它,如果一切顺利,我可以简单地将它们组合在一起。我设法(经过一番努力)让每个部分都工作但是当我将它们组合在一起时它不起作用(我在eclipse和QT创建者中都尝试过.QT创建者说它出乎意料地退出而且eclipse刚刚停止......)
这是解析部分(它完全符合我的要求):
#include <string.h>
#include <stdio.h>
int main()
{
char line[1024] = "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 4],";
size_t len = strlen(line);
memmove(line, line+1, len-3);
line[len-3] = 0;
printf("%s \n",line);
char str[100], *s = str, *t = NULL;
strcpy(str, line);
while ((t = strtok(s, " ,")) != NULL) {
s = NULL;
printf(":%s:\n", t);
}
return 0;
}
如果我打印文件的每一行,变量行中的数据就像我得到的那样。但是当我将它复制/粘贴到我的主程序中时,它就不起作用(QT没有显示任何内容,eclipse只显示第一行)。这段代码只是几个文件IO命令,它们包含在上面的命令中(while循环中的所有内容与上面的完全相同)
#include <stdio.h>
#include <stdlib.h>
int main() {
char line[1024];
FILE *fp = fopen("/Users/me/Desktop/output.txt","r");
printf("Starting.. \n");
int count = 0;
int list[30]; //items will be stored here
while(fgets(line, 1024, fp) != NULL){
count++;
//char line[1024] = "[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 4],";
size_t len = strlen(line);
memmove(line, line+1, len-4);
line[len-4] = 0;
printf("%s \n",line);
char *s = str, *t = NULL;
strcpy(str, line);
while ((t = strtok(s, " ,")) != NULL) {
s = NULL;
printf(":%s:\n", t);
}
}
printf(" num of lines is %i \n", count);
return 0;
}
eclipse输出:
Starting..
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 4
我无法弄清楚我做错了什么。我正在使用带有gcc 4.2的mac,如果有帮助的话。我唯一能想到的可能就是我在解析list变量的方式上做错了所以以后无法访问它(我不确定这是一个疯狂的猜测)。有什么我想念的吗?
编辑:如果我注释掉这段代码,它会通过该文件(但不解析):
while ((t = strtok(s, " ,")) != NULL) {
s = NULL;
printf(":%s:\n", t);
}
该文件的内容基本上是:
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 4],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 4],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 2, 2, 4],
依此类推(20 + gb)。
EDIT2:我只是想测试它是否与我的mac一起,我在centos 5上尝试过(安装它只是为了测试)从命令行运行时我得到了同样的错误,除了最后它说{ {1}}。我所做的只是将上面的示例输出复制到一个文件中,并在上面的代码中更改了路径并运行它。
答案 0 :(得分:4)
这里有两个line
声明 - 一个在main()
之后,一个在while
之后。 fgets
读入第一个line
变量。在while块中,第二个line
声明掩盖了第一个(因为第二个更加本地化)。外部line
变量 - fgets
读入的变量 - 不会在程序中的任何其他位置访问。
答案 1 :(得分:3)
我明白了!尝试插入#include <string.h>
与其他包含。我不知道你为什么使用函数<string.h>
而没有包含它,但它导致错误的链接。编译器发出以下警告:
test2.c:17: warning: incompatible implicit declaration of built-in function ‘strlen’
test2.c:18: warning: incompatible implicit declaration of built-in function ‘memmove’
test2.c:24: warning: incompatible implicit declaration of built-in function ‘strcpy’
test2.c:25: warning: assignment makes pointer from integer without a cast
前三个警告表示您未包含头文件。 最后一个只是表明没有声明,假定函数采用并返回整数(这是为了向后兼容古代C代码)。
不要忘记fgets
包含行尾的换行符。您需要将len-3
更改为len-4
。
另外,完成后请不要忘记fclose
文件。
此外,您的memmove是不必要的,因为您可以指向第二个字符:
char *moved_line = line + 1;