我的程序逐行读入文本文件,并打印出每个句子行中最大的单词。但是,它有时打印出以前最高的单词,尽管它们与当前句子无关,我在处理每一行时重置了我的char数组。有人可以向我解释记忆中发生了什么来实现这一目标吗?感谢。
//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 line with text
another line of words
Jimmy John took the a apple and something reallyreallylongword it was nonsense
test test BillGatesSteveJobsWozWasMagnificant
a b billy
程序的输出是。
some
another
reallyreallylongword
BillGatesSteveJobsWozWasMagnificantllyreallylongword
BillGatesSteveJobsWozWasMagnificantllyreallylongword //should be billy
当我随意改变第5个句子的长度时,有时也会使用最后一个词 出现了&#34;真正的长篇大论&#34;这很奇怪。
编辑:即使我评论MEMSET,我仍然得到相同的结果,因此它可能与memset没有任何关系但不完全确定
答案 0 :(得分:3)
尾随空字节(\ 0)是字符串操作的祸根。你有一个复制序列,它不是你想要的那样:
strncpy(sub, sentence, strlen(sentence)-1);
strcpy(sentence, sub);
句子被复制到sub中,然后再次返回。除此之外,strncpy不会复制&#39; \ 0&#39;出于句子。将字符串从子句复制回句子时,您将未知长度的数据复制回句子。因为堆栈正在被重用并且char数组未初始化,所以数据可能位于前一次迭代中,因此可以在下次执行时看到。
在两个strcpys之间添加以下内容可以解决问题:
sub[strlen(sentence) - 1] = '\0';
答案 1 :(得分:1)
你有一个缺少的空终止符。
char sub[100];
char maxWord[100];
strncpy(sub, sentence, strlen(sentence)-1);
strcpy(sentence, sub);
当你strncpy
时,如果src长于要复制的字符数,则不添加空终止符。你已经保证会出现这种情况,因此sub
没有终止符,你很快就会遇到你不想要的行为。看起来你正试图修剪字符串中的最后一个字符;更简单的方法是将索引strlen(sentence)-1
处的字符设置为'\0'
。
答案 2 :(得分:1)
这很糟糕:
strncpy(sub, sentence, strlen(sentence)-1);
strcpy(sentence, sub);
如果源字符串不适合,strncpy
函数不会空终止其缓冲区。通过strlen(sentence)-1
,你保证它不适合。然后strcpy
导致未定义的行为,因为sub
不是字符串。
我的建议是不使用strncpy
,它几乎不是解决问题的好方法。使用strcpy
或snprintf
。
在这种情况下,您甚至不会使用sub
,因此您可以将这些行替换为:
sentence[ strlen(sentence) - 1 ] = 0;
具有删除fgets留下的\n
的效果。 (如果输入超过100,则删除输入字符。)
答案 3 :(得分: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;
}
确保文件最后关闭。这是一种很好的做法。