用C语言读取文件

用C语言读取文件,c,string,C,String,我正在读取C程序中的一个文件,并将其中的每个单词与我的单词进行比较,这是通过命令行参数输入的。但我会撞车,我不知道怎么了。如何跟踪此类错误?我的情况怎么了 我的编译器叮当作响。代码编译得很好。运行时显示“分段故障” 这是代码 #include <stdio.h> #include <string.h> int main(int argc, char* argv[]) { char* temp = argv[1]; char* word = strcat(

我正在读取C程序中的一个文件,并将其中的每个单词与我的单词进行比较,这是通过命令行参数输入的。但我会撞车,我不知道怎么了。如何跟踪此类错误?我的情况怎么了

我的编译器叮当作响。代码编译得很好。运行时显示“分段故障”

这是代码

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

int main(int argc, char* argv[])
{
    char* temp = argv[1];
    char* word = strcat(temp, "\n");

    char* c = "abc";
    FILE *input = fopen("/usr/share/dict/words", "r");

    while (strcmp(word, c))
    {
        char* duh = fgets(c, 20, input);
        printf("%s", duh); 
    }

    if (!strcmp (word, c))
    {
        printf("FOUND IT!\n");
        printf("%s\n%s", word, c);  
    }

    fclose(input);    
}
#包括
#包括
int main(int argc,char*argv[])
{
char*temp=argv[1];
char*word=strcat(temp,“\n”);
char*c=“abc”;
FILE*input=fopen(“/usr/share/dict/words”,“r”);
while(strcmp(word,c))
{
char*duh=fgets(c,20,输入);
printf(“%s”,duh);
}
如果(!strcmp(字,c))
{
printf(“找到了!\n”);
printf(“%s\n%s”,单词,c);
}
fclose(输入);
}

我看到的第一个问题是:

string word = strcat(argv[1], "\n");
您正在将字符添加到缓冲区的末尾。 运行时环境为您分配的缓冲区,您应该考虑只读。< /P> 编辑

恐怕您对代码的更改仍然具有相同的效果

char* temp = argv[1];
temp
指向与
argv[1]
相同的缓冲区。 您需要分配一个适当大小的缓冲区,并使用它

char* temp = (char*)malloc(sizeof(char) * (strlen(argv[1]) + 2));
+2
用于在末尾添加
\n
\0
。 然后你可以这样做:

strcpy(temp, argv[1]);
strcat(temp,"\n");

我看到的第一个问题是:

string word = strcat(argv[1], "\n");
您正在将字符添加到缓冲区的末尾。 运行时环境为您分配的缓冲区,您应该考虑只读。< /P> 编辑

恐怕您对代码的更改仍然具有相同的效果

char* temp = argv[1];
temp
指向与
argv[1]
相同的缓冲区。 您需要分配一个适当大小的缓冲区,并使用它

char* temp = (char*)malloc(sizeof(char) * (strlen(argv[1]) + 2));
+2
用于在末尾添加
\n
\0
。 然后你可以这样做:

strcpy(temp, argv[1]);
strcat(temp,"\n");

首先,我的C语言知识很老,所以我不确定字符串是什么。无论哪种方式,它都是有帮助的,但不是绝对需要有一个好的预调零缓冲区来读取文件的内容。因此,无论您是将word设置为零,还是执行如下操作,请先将输入设置为零

#define IN_BUF_LEN 120
char in_buf[IN_BUF_LEN] = {0};
120个字符是一个安全的大小,假设您的大多数文本行长度约为80个字符或更少

第二,您是基于strcmp
strcmp
值的循环,而不是实际读取文件。它可能完成同样的事情,但我的
while
基于到达文件末尾

最后,您声明了
duh
一个指针,而不是存储
fgets
返回内容的位置。这也是一个问题。因此,
duh
的声明应该与上面的
类似


最后,您将在编译时而不是运行时分配
argv[1]
的值。我看不出这能让你得到你想要的。如果将
temp
声明为指针,然后将
argv[1]
赋值给它,则只会有另一个指向
argv[1]
的指针,但实际上没有将
argv[1]
的值复制到局部变量。为什么不直接使用argv[1]

首先,我的C语言知识很老,所以我不确定字符串是什么。无论哪种方式,它都是有帮助的,但不是绝对需要有一个好的预调零缓冲区来读取文件的内容。因此,无论您是将word设置为零,还是执行如下操作,请先将输入设置为零

#define IN_BUF_LEN 120
char in_buf[IN_BUF_LEN] = {0};
120个字符是一个安全的大小,假设您的大多数文本行长度约为80个字符或更少

第二,您是基于strcmp
strcmp
值的循环,而不是实际读取文件。它可能完成同样的事情,但我的
while
基于到达文件末尾

最后,您声明了
duh
一个指针,而不是存储
fgets
返回内容的位置。这也是一个问题。因此,
duh
的声明应该与上面的
类似


最后,您将在编译时而不是运行时分配
argv[1]
的值。我看不出这能让你得到你想要的。如果将
temp
声明为指针,然后将
argv[1]
赋值给它,则只会有另一个指向
argv[1]
的指针,但实际上没有将
argv[1]
的值复制到局部变量。为什么不使用<代码> ARGV [1 ] < /> >

< p>这里的问题是,你试图用C语言处理字符串,就像你可以用另一种语言(比如C++或java)那样,它们是可调整的向量,你可以很容易地将任意数量的数据附加或读取到.< /p>中。 C字符串的级别要低得多。它们只是一个字符数组(或指向这样一个数组的指针;数组可以被视为指向其在C中的第一个元素的指针),字符串被视为该数组中直到第一个空字符的所有字符。这些阵列是固定大小的;如果您想要一个任意大小的字符串,您需要使用
malloc()
自己分配它,或者在堆栈上以您想要的大小分配它

这里有一点让人困惑的是,您使用的是非标准类型
string
。考虑到上下文,我假设它来自您的
cs50.h
,只是
char*
的一个typedef。如果您实际使用
char*
而不是
string
,可能会减少混淆;使用typedef会掩盖真正发生的事情

让我们从第一个问题开始

    string word = strcat(argv[1], "\n");
strcat()
将第二个字符串附加到第一个字符串上;它从第一个字符串的null终止符开始,并用第二个字符串的第一个字符替换它,依此类推,直到它在第二个字符串中达到null。为了让它工作,包含第一个字符串的缓冲区需要有足够的空间来容纳第二个字符串。否则,您可能会覆盖其他任意内存,从而导致程序崩溃
    string c = "abc";

    // ...

        char* duh = fgets(c, 20, input);
char c[20];
char *c = malloc(20);
char* duh = fgets(c, 20, input);
#define BUFFERSIZE 1024
...
while (reasonable condition) {
    char *duh = malloc(BUFERSIZE);
    if (NULL == duh) { /* not enough memory - handle error, and exit */
    }
    duh = fgets(duh, BUFFERSIZE, input);
    if (NULL == duh) { /* handle error or EOF condition */
    } else { /* check that the line is read completely,
        i.e. including end-of-line mark,
        then do your stuff with the data */
    }
    free (duh);
}