C-仅在声明整数时,程序才能起作用



我实际上是在尝试一些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("nnt* * * * * * * * * * * * * * * * * * * * * nn");
    }
    else
    {
        printf("nFile Does not Existn");
    }
    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("nnt* * * * * * * * * * * * * * * * * * * * * nn");
    }
    else
    {
        printf("nFile Does not Existn");
    }
    return 0;
}

我正在使用GCC编译器

gcc -v

使用内置规格。collect_gcc = GCC collect_lto_wrapper =/usr/lib/gcc/x86_64-linux-gnu/4.6/lto-wrapper 目标:x86_64-linux-gnu配置为:../src/configure -v -with-pkgversion ='ubuntu/linaro 4.6.3-1ubuntu5'-with-bugurl = file:///usr/share/doc/gcc/gcc-4.6/readme.bugs-enable-languages = c,c ,, c ,,fortran,objc,obj-c -preifix =/usr -program-suffix = -4.6-- enable-shared - enable-link-build-build-id - with-system-zlib -libexecdir =/usr/lib - 不包含 - getText - enable-threads = posix -with-with-gxx-include-dir =/usr/include/c /4.6 - libdir =/usr/usr/lib-enable-enable-nls - with-sysroot - with-sysroot=/ - enable-clocale = gnu-可启用libstdcxx-debug - enable-enable-libstdcxx time = yes-eenable-enable-enable-gnu-nique-object - enable-enable-plugin-enable-plugin-enable-enable-objc-gc -disable-disable-diesable-diesable-werror -with-ark-32 = i686 -with-tune = generic -enable-checking = repares-build = x86_64-linux-gnu -host = x86_64-linux-gnu -target -target = x86_64-linux-linux--linux--linux--linux--GNU线程模型:POSIX GCC版本4.6.3(Ubuntu/Linaro 4.6.3-1ubuntu5)

任何人都可以解释这里发生的事情,我想知道为什么会发生这种情况。

您不是在为line缓冲区分配内存,在您的情况下,这只是无效的指针

在第一种情况下,您很幸运,因为指针指向了一个可写的区域(特别是您正在覆盖count所在的内存区域),但是在第二种情况下,分段错误是提起。

替换:

char *line; // Pointer to... somewhere?

with:

char line[4096];

或任何其他合适的缓冲尺寸。如果您需要不适合堆栈的缓冲区,请将其声明为全局变量(强烈劝阻,除非您的应用程序真的很小或您知道您在做什么)或在堆上分配:

char *line = malloc(4096 * 1024);

并记住在不再需要缓冲区的时候致电free(line)(例如,在终止程序之前)。

char *line;

应该像

char line[1024];

并添加一个fclose。

由于评论而编辑:
如果您想要第一个定义和malloc/free:

char *line;
line = malloc(1024);
...
free(line);

fscanf将char *line;指向的缓冲区写入一个缓冲区,但从未设置为有用的线路。大概添加额外的INT会导致内存布局有所不同,因此它以不同的方式破裂。

更好,至少在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),但最长的行可能小于例如。512字节(在我的i3770k上带有Linux 3.13内核,它具有483个字节)。知道(这不是完全保证的,但今天是正确的,请参见Proc(5))您可以简单地用fgets(3)

代码
char linebuf[512];
do {
  if (fgets(linebuf,sizeof(linebuf),file)==0) break;
  fputs(linebuf, stdout);
} while(!feof(linebuf));

提防(3)之后(不是之前)某些<stdio.h>输入操作(此处 fgets)。

ps。不要忘记使用所有警告和调试信息(例如gcc -Wall -g)并使用调试器(gdb)。

最新更新