我实际上正在尝试一些C编程代码,我想出了这个程序,由于某种原因它只在声明一个整数并且被赋予一些值时起作用。
以下代码完美无缺
#include<stdio.h>
int main()
{
FILE *file = fopen("/proc/cpuinfo","r");
char *line;
int count = 0;
if(file!=NULL)
{
while(fscanf(file," %[^\n]",line)!=-1)
{
printf("\n%s",line);
}
printf("\n\n\t* * * * * * * * * * * * * * * * * * * * * \n\n");
}
else
{
printf("\nFile Does not Exist\n");
}
return 0;
}
但是这不起作用,(我的意思是,当我运行它时,我得到一个无限循环的(null)值。
#include<stdio.h>
int main()
{
FILE *file = fopen("/proc/cpuinfo","r");
char *line;
if(file!=NULL)
{
while(fscanf(file," %[^\n]",line)!=-1)
{
printf("\n%s",line);
}
printf("\n\n\t* * * * * * * * * * * * * * * * * * * * * \n\n");
}
else
{
printf("\nFile Does not Exist\n");
}
return 0;
}
我正在使用gcc编译器
gcc -v
使用内置规格。 COLLECT_GCC = GCC COLLECT_LTO_WRAPPER = / usr / lib中/ GCC / x86_64的-Linux的GNU / 4.6 / LTO-包装 目标:x86_64-linux-gnu配置为:../ src / configure -v --with-pkgversion ='Ubuntu / Linaro 4.6.3-1ubuntu5'--with-bugurl = file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages = c,c ++, fortran,objc,obj-c ++ --prefix = / usr --program-suffix = -4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir = / usr / lib --without-included-gettext --enable-threads = posix --with-gxx-include-dir = / usr / include / c ++ / 4.6 --libdir = / usr / lib --enable-nls --with-sysroot = / --enable-clocale = gnu --enable-libstdcxx-debug --enable-libstdcxx-time = yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --disable- werror --with-arch-32 = i686 --with-tune = generic --enable-checking = release --build = x86_64-linux-gnu --host = x86_64-linux-gnu --target = x86_64-linux- gnu线程模型:posix gcc版本4.6.3(Ubuntu / Linaro 4.6.3-1ubuntu5)
任何人都可以解释这里发生的事情,我想知道为什么会这样。
答案 0 :(得分:3)
您没有为line
缓冲区分配内存,在这种情况下,只有无效指针。
在第一种情况下,你是幸运的,因为指针指向一个可写区域(具体来说,你覆盖了count
所在的内存区域),但在第二种情况下,引发了分段错误。
替换:
char *line; // Pointer to... somewhere?
使用:
char line[4096];
或任何其他合适的缓冲区大小。如果你需要一个不适合堆栈的缓冲区,那么将它声明为全局变量(强烈建议不要使用,除非你的应用程序非常小或你知道你在做什么)或者在堆上分配它,并使用:
char *line = malloc(4096 * 1024);
并且记得在不再需要缓冲区时调用free(line)
(例如在终止程序之前)。
答案 1 :(得分:2)
char *line;
应该是
char line[1024];
并添加一个fclose。
因评论而编辑:
如果你想要第一个定义和malloc / free:
char *line;
line = malloc(1024);
...
free(line);
答案 2 :(得分:1)
fscanf写入char *line;
指向的缓冲区,但行永远不会设置为指向任何有用的地方。据推测,添加额外的int会导致内存布局略有不同,因此它会以不同的方式中断。
答案 3 :(得分:0)
更好的是,至少在Linux上,您可以使用getline(3)
int main() {
FILE *file = fopen("/proc/cpuinfo","r");
char *line=NULL;
size_t linesiz= 0;
ssize_t linelen= -1;
if (file == NULL) { perror("/proc/cpuinfo"); exit (EXIT_FAILURE); };
while ((linelen=getline(&line,&linesiz))>=0)
fputs(line,stdout);
free(line), line=NULL;
fclose(file);
}
然而,在实践中,我们都知道/proc/cpuinfo
包含一些长行(特别是flags
),但可能最长的行少于例如char linebuf[512];
do {
if (fgets(linebuf,sizeof(linebuf),file)==0) break;
fputs(linebuf, stdout);
} while(!feof(linebuf));
。 512字节(在我的i3770K上使用Linux 3.13内核,它有483字节)。知道(这不是完全保证,但今天是真的,请参阅proc(5)),您只需使用fgets(3)进行编码
<stdio.h>
请注意feof(3)应在fgets
输入操作之后(不是之前)使用(此处为gcc -Wall -g
)。
PS。不要忘记编译所有警告和调试信息(例如gdb
)并使用调试器({{1}})。