C文件编译但未运行

时间:2016-06-04 01:22:49

标签: c

所以我的程序将文件作为输入并解析出空格。令牌被保存到一个数组中。我有一个函数来打印出数组的内容,以测试解析器是否正常工作。代码用gcc -o filename filename.c编译。但是当我运行程序并给它一个文件路径时,我得到一个弹出窗口,指示filename.exe已停止工作:一个问题导致程序停止正常工作。如果有可用的解决方案,Windows将关闭该程序并通知您。

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
char file_name[100];
char *token_array[256];
int main()
{
   char ch;
   FILE *fp;

   int n=0;
   char *str;

   printf("Enter filepath\n");
   gets(file_name);

   fp = fopen(file_name,"r"); 

   if( fp == NULL )
   {
      perror("Error opening the file.\n");
      exit(EXIT_FAILURE);
   }

   int i = 0;         
   char *p; 
   while( ( ch = fgetc(fp) ) != EOF )
   {
    char *fgets(char *str, int n, FILE *stream);
    p = strtok(str, " ");
    i=0;

    while(p!=NULL)
    {
        strcpy(token_array[i], p);
    }

    i++;

   }

   for(n=0;n<256;n++)
   {
      printf("%s", &token_array[n]);
   }

   return 0;
}

2 个答案:

答案 0 :(得分:1)

此行没有任何作用:

char *fgets(char *str, int n, FILE *stream);

如上所述,该行只不过是函数的声明,可能不是你想要的。

如果您要使用fgets(),请单独使用fgets(),不要将其与fgetc()混用:

char str[1024];
while ( fgets( str, sizeof( str ), fp )
{
   .
   .
   .

fgets()NULL或{错误情况}时返回EOF。请注意str不是char *,而是char数组。更好的解决方案是使用getline(),因为具有固定长度缓冲区的fgets()只能读取适合缓冲区的整行。更长的线将被拆分。

fgetc()返回int,而不是char。但是,当您使用fgetc()从文件中读取行时,不应使用fgets()。选择一个并使用它。但是如果你使用fgetc(),则需要编写代码,以便在逐行读取时将每行放在一起。

token_array[i]指向的是什么?您将token_array声明为指针数组:

char *token_array[256];

但是你永远不会为数组中的每个指针分配任何内存来指向。

最简单的解决方案是改变

strcpy(token_array[i], p);

token_array[i] = strdup(p);

假设您的平台有strdup(),相当于malloc()返回的内存的strcpy()malloc(),因此您需要调用free()你从strdup()获得的字符串。

您使用strtok()是错误的。有关正确strtok()用法的示例,请参阅How does strtok() split the string into tokens in C?

由于token_array是一个char *指针数组,所以

printf("%s", &token_array[n]);

将获取实际指针本身的地址,而不是它应该指向的字符串。然后它将尝试在包含指针变量的内存中打印出一个“字符串”。这不会很好。由于它已经是char *,您只需要:

printf("%s", token_array[n]);

答案 1 :(得分:1)

您可以尝试使用此代码。我更改了您的程序,以便它可以读取和标记文件。

$.fn.dataTable.moment( 'D MMMM YYYY HH:mm:ss', 'fr');

<强> data.txt中

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

char *trim(char *s) {
    int i = strlen(s) - 1;
    if (s[i] == '\n')
        s[i] = '\0';
    return s;
}

#define BUFFER_SIZE 100
char *token_array[256];
int main( int argc, char** argv ){

    const char *delimiter_characters = " ";
    char *filename =  malloc(BUFFER_SIZE);

    int i = 0;
    printf("Enter filepath\n");
    fgets(filename, 100, stdin);


    FILE *input_file = fopen( trim(filename), "r" );
    char buffer[ BUFFER_SIZE ];
    char *last_token;

    if( input_file == NULL ){

        fprintf( stderr, "Unable to open file %s\n", filename );

    }else{

        // Read each line into the buffer
        while( fgets(buffer, BUFFER_SIZE, input_file) != NULL ){

            // Write the line to stdout
            //fputs( buffer, stdout );

            // Gets each token as a string and prints it
            last_token = strtok( buffer, delimiter_characters );
            while( last_token != NULL ){
                //printf( "%s\n", last_token );
                token_array[i] = malloc(100);
                strcpy(token_array[i], last_token);
                i++;
                last_token = strtok( NULL, delimiter_characters );
            }

        }

        if( ferror(input_file) ){
            perror( "The following error occurred" );
        }

        fclose( input_file );

    }
    int n;
    for(n=0;token_array[n] != NULL && n<256;n++)
    {
        printf("%s", token_array[n]);
        free(token_array[n]);
    }
    free(filename);
    return 0;

}

<强>测试

Hello Foo Bar
How are you?

数组的内容是

Debug/gnu
Enter filepath
data.txt
HelloFooBar
Howareyou?
Process finished with exit code 0

如果添加调试信息,则可以看到数组的内容:

n[0] Hello n[1] Foo n[2] Bar n[3] How n[4] are n[5] you?