所以我的程序将文件作为输入并解析出空格。令牌被保存到一个数组中。我有一个函数来打印出数组的内容,以测试解析器是否正常工作。代码用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;
}
答案 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?