Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C-char数组在memset之后获取幻象值_C_Arrays_Char - Fatal编程技术网

C-char数组在memset之后获取幻象值

C-char数组在memset之后获取幻象值,c,arrays,char,C,Arrays,Char,我的程序逐行读取文本文件,并打印出每行句子中最大的单词。然而,它有时会打印出前面最高的单词,尽管它们与当前句子无关,并且我在处理每一行的末尾重置了我的字符数组。有人能向我解释一下记忆中发生了什么使这一切发生吗?谢谢 //Program Written and Designed by R.Sharpe //LONGEST WORD CHALLENGE //Purpose: Find the longest word in a sentence #include <stdio.h> #

我的程序逐行读取文本文件,并打印出每行句子中最大的单词。然而,它有时会打印出前面最高的单词,尽管它们与当前句子无关,并且我在处理每一行的末尾重置了我的字符数组。有人能向我解释一下记忆中发生了什么使这一切发生吗?谢谢

//Program Written and Designed by R.Sharpe
//LONGEST WORD CHALLENGE
//Purpose: Find the longest word in a sentence

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

int main(int argc, char** argv)
{
    FILE* file;
    file = fopen(argv[1], "r");
    char* sentence = (char*)malloc(100*sizeof(char));
    while(fgets(sentence, 100, file) != NULL)
    {
        //printf("%s\n", sentence);
        char sub[100];
        char maxWord[100];
        strncpy(sub, sentence, strlen(sentence)-1);
        strcpy(sentence, sub);
        char* word;
        int maxLength = 0;
        word = strtok(sentence, " ");
        while(word != NULL)
        {
            if(strlen(word) > maxLength)
            {
                maxLength = strlen(word);
                strcpy(maxWord, word);
                //printf("%s\n", maxWord);
            }
            word = strtok(NULL, " ");
        }
        printf("%s\n", maxWord);
        memset(maxWord, 0, sizeof(char));
        maxLength = 0; //reset for next sentence;
    }
    free(sentence);
    return 0; 
}
程序的输出是

some
another
reallyreallylongword
BillGatesSteveJobsWozWasMagnificantllyreallylongword
BillGatesSteveJobsWozWasMagnificantllyreallylongword //should be billy
有时,当我随意改变第五句的长度时,最后一个词也会改变 结果是“真正的长单词”,这很奇怪。

编辑:即使我对MEMSET进行注释,我仍然会得到相同的结果,因此它可能与MEMSET无关,但不能完全确定尾随空字节(\0)是字符串操作的祸根。您有一个复制序列,但它并不是您想要的:

    strncpy(sub, sentence, strlen(sentence)-1);
    strcpy(sentence, sub);
句子被复制成子句,然后再复制回来。除此之外,strncpy不会从句子中复制“\0”。当您将字符串从sub复制回句子中时,您正在将未知长度的数据复制回句子中。因为堆栈被重用,而字符数组未初始化,所以数据可能在上一次迭代中驻留在那里,因此在下一次执行时可以看到

在两个strcpy之间添加以下内容可修复此问题:

sub[strlen(sentence) - 1] = '\0';
尾随的空字节(\0)是字符串操作的祸根。您有一个复制序列,但它并不是您想要的:

    strncpy(sub, sentence, strlen(sentence)-1);
    strcpy(sentence, sub);
句子被复制成子句,然后再复制回来。除此之外,strncpy不会从句子中复制“\0”。当您将字符串从sub复制回句子中时,您正在将未知长度的数据复制回句子中。因为堆栈被重用,而字符数组未初始化,所以数据可能在上一次迭代中驻留在那里,因此在下一次执行时可以看到

在两个strcpy之间添加以下内容可修复此问题:

sub[strlen(sentence) - 1] = '\0';

您缺少一个空终止符

char sub[100];
char maxWord[100];
strncpy(sub, sentence, strlen(sentence)-1);
strcpy(sentence, sub);

当您
strncpy
时,如果src大于要复制的字符数,则不会添加空终止符。您已经保证了这种情况,因此
sub
没有终止符,您很快就会遇到不想要的行为。看起来您正试图从字符串中删除最后一个字符;更简单的方法是将索引strlen(句子)-1处的字符设置为
'\0'

缺少空终止符

char sub[100];
char maxWord[100];
strncpy(sub, sentence, strlen(sentence)-1);
strcpy(sentence, sub);
当您
strncpy
时,如果src大于要复制的字符数,则不会添加空终止符。您已经保证了这种情况,因此
sub
没有终止符,您很快就会遇到不想要的行为。看起来您正试图从字符串中删除最后一个字符;更简单的方法是将索引strlen(句子)-1中的字符设置为
'\0'

这很糟糕:

strncpy(sub, sentence, strlen(sentence)-1);
strcpy(sentence, sub);
如果源字符串不合适,
strncpy
函数不为null并终止其缓冲区。通过执行strlen(句子)-1,您保证它不合适。然后,
strcpy
会导致未定义的行为,因为
sub
不是字符串

我的建议是不要使用strncpy,它几乎从来都不是解决问题的好方法。使用
strcpy
snprintf

在这种情况下,您甚至从不使用
sub
,因此可以将这些行替换为:

sentence[ strlen(sentence) - 1 ] = 0;
其作用是删除fgets留下的一端的
\n
。(如果输入长度超过100,则会删除输入的一个字符)。

这是错误的:

strncpy(sub, sentence, strlen(sentence)-1);
strcpy(sentence, sub);
如果源字符串不合适,
strncpy
函数不为null并终止其缓冲区。通过执行strlen(句子)-1,您保证它不合适。然后,
strcpy
会导致未定义的行为,因为
sub
不是字符串

我的建议是不要使用strncpy,它几乎从来都不是解决问题的好方法。使用
strcpy
snprintf

在这种情况下,您甚至从不使用
sub
,因此可以将这些行替换为:

sentence[ strlen(sentence) - 1 ] = 0;

其作用是删除fgets留下的一端的
\n
。(如果输入长度超过100,则会删除输入的一个字符)。

在下面找到更正的代码

int main(int argc, char** argv)
{
    FILE* file;
    file = fopen(argv[1], "r");
     char sub[100];
     char maxWord[100];
      char* word;
      int maxLength = 0;

    char* sentence = (char*)malloc(100*sizeof(char));

    while(fgets(sentence, 100, file) != NULL)
    {
        maxLength = 0;
        strncpy(sub, sentence, strlen(sentence)-1);
        sub[strlen(sentence) - 1] = '\0'; //Fix1
        strcpy(sentence, sub);
        word = strtok(sentence, " ");

        while(word != NULL)
        {

            if(strlen(word) > maxLength)
            {
                maxLength = strlen(word);
                strcpy(maxWord, word);

            }
                    word = strtok(NULL, " ");

        }
        printf("%s\n", maxWord);
        memset(maxWord, 0, sizeof(char));
        maxLength = 0; //reset for next sentence;
    }
    free(sentence);
    fclose (file); //Fix2
    return 0; 
}

确保文件在结尾处已关闭。这是一种很好的做法。

在下面找到正确的代码

int main(int argc, char** argv)
{
    FILE* file;
    file = fopen(argv[1], "r");
     char sub[100];
     char maxWord[100];
      char* word;
      int maxLength = 0;

    char* sentence = (char*)malloc(100*sizeof(char));

    while(fgets(sentence, 100, file) != NULL)
    {
        maxLength = 0;
        strncpy(sub, sentence, strlen(sentence)-1);
        sub[strlen(sentence) - 1] = '\0'; //Fix1
        strcpy(sentence, sub);
        word = strtok(sentence, " ");

        while(word != NULL)
        {

            if(strlen(word) > maxLength)
            {
                maxLength = strlen(word);
                strcpy(maxWord, word);

            }
                    word = strtok(NULL, " ");

        }
        printf("%s\n", maxWord);
        memset(maxWord, 0, sizeof(char));
        maxLength = 0; //reset for next sentence;
    }
    free(sentence);
    fclose (file); //Fix2
    return 0; 
}

确保文件在结尾处已关闭。这是一个很好的做法。

我补充说,它没有改变任何东西。旁注,您可以更简单地将句子的最后一个字符设置为
\0
strncpy(sub,句子,strlen(句子)-1)创建未终止的数组,因为您禁止它写入终止字符串所需的null。您不能将其传递给字符串函数,但这正是您在下一行所做的。我补充说,它没有改变任何内容。请注意,您可以更简单地将句子的最后一个字符设置为
\0
strncpy(sub,句子,strlen(句子)-1)创建未终止的数组,因为您禁止它写入终止字符串所需的null。您不能将其传递给字符串函数,但这正是您在下一行中所做的。因此,空终止符字符是否与换行符一起包含在字符数组的大小中?i、 e.strlen(句子)=对于所有字符+'/n'+'/0'?@user3312266在计算
strlen
时,字符串中除了
'\0'
之外的所有内容都包括在内,因此strlen(句子)=对于所有字符+'/n'。字符数组的大小中是否包括空终止符字符以及换行符?i、 e.strlen(句子)=所有字符+'/n'+'