求解答:问为什么strcmp()函数部分比较一直为0
【题目】输入一行句子,统计有多少个单词(单词间以,或空格隔开,以!或.结束),并把这些单词按照字母序排序输出。
#include<bits/stdc++.h>
using namespace std;
char a[10010],word[99][1010],pai[1010];
int cnt=1,len,order=1;
void swapp(char * str,char *str1)
{
char str2[1010];
strcpy(str2,str);
strcpy(str,str1);
strcpy(str1,str2);
}
void check(char c)//存单词
{
if(c>='a'&&c<='z'||c>='A'&&c<='Z')
{
word[cnt][order]=c;
//cout<<word[cnt][order];
order++;
}
else {
//cout<<endl;
cnt++;
order=1;
}
}
int main()
{
gets(a);
len=strlen(a);
for(int i=0;i<len;i++){
if(a[i]!='!'||a[i]!='.'){
check(a[i]);
}
else break;
}
//冒泡排序
cnt-=1;
int i,j;
for(int i=1;i<=cnt;++i)
{
for(int j=1;j<=cnt-i;++j)
{
cout<<strcmp(word[j],word[i])<<endl; //???比大小出错
if((strcmp(word[j],word[j+1]))>0){
cout<<"chang";
swapp(word[j],word[j+1]);
}
}
}
//输出
cout<<cnt<<endl;
for(int i=1;i<=cnt;++i){
int j=1;
while(1)
{
if(word[i][j]>='a'&&word[i][j]<='z'||word[i][j]>='A'&&word[i][j]<='Z')
{
cout<<word[i][j];
j++;
}
else break;
}
cout<<endl;
}
return 0;
}
修正和改进的地方包括:
1、替换了 gets 函数为 cin.getline 函数,gets 函数存在安全性问题。
2、修改了一些变量名和注释,使代码更易读。
3、’提取单词时修复了最后一个单词可能被忽略的问题。
4、使用 sort 函数对单词进行排序,而不是手动实现冒泡排序。
5、简化了输出部分的代码。
请注意,此代码假设输入的句子不超过 MAX_WORD_LENGTH 字符,并且单词数不超过 MAX_WORDS 个。你可以根据实际需要进行调整。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#pragma warning(disable:4996)
const int MAX_WORDS = 99;
const int MAX_WORD_LENGTH = 1010;
char sentence[MAX_WORD_LENGTH];
char* words[MAX_WORDS];
int wordCount = 0;
bool isWordSeparator(char c) {
return (c == ' ' || c == ',');
}
void extractWords() {
int len = strlen(sentence);
int wordIndex = 0;
int charIndex = 0;
for (int i = 0; i < len; i++) {
if (isWordSeparator(sentence[i])) {
if (charIndex > 0) {
words[wordIndex] = new char[charIndex + 1];
strncpy(words[wordIndex], sentence + i - charIndex, charIndex);
words[wordIndex][charIndex] = '\0';
wordIndex++;
charIndex = 0;
}
}
else {
charIndex++;
}
}
if (charIndex > 0) {
words[wordIndex] = new char[charIndex + 1];
strncpy(words[wordIndex], sentence + len - charIndex, charIndex);
words[wordIndex][charIndex] = '\0';
wordIndex++;
}
wordCount = wordIndex;
}
bool compareWords(const char* word1, const char* word2) {
return strcmp(word1, word2) < 0;
}
int main() {
cin.getline(sentence, MAX_WORD_LENGTH);
extractWords();
sort(words, words + wordCount, compareWords);
cout << wordCount << endl;
for (int i = 0; i < wordCount; i++) {
cout << words[i] << endl;
delete[] words[i];
}
return 0;
}
以下是使用冒泡排序的版本:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#pragma warning(disable:4996)
const int MAX_WORDS = 99;
const int MAX_WORD_LENGTH = 1010;
char sentence[MAX_WORD_LENGTH];
char* words[MAX_WORDS];
int wordCount = 0;
bool isWordSeparator(char c) {
return (c == ' ' || c == ',');
}
void extractWords() {
int len = strlen(sentence);
int wordIndex = 0;
int charIndex = 0;
for (int i = 0; i < len; i++) {
if (isWordSeparator(sentence[i])) {
if (charIndex > 0) {
words[wordIndex] = new char[charIndex + 1];
strncpy(words[wordIndex], sentence + i - charIndex, charIndex);
words[wordIndex][charIndex] = '\0';
wordIndex++;
charIndex = 0;
}
}
else {
charIndex++;
}
}
if (charIndex > 0) {
words[wordIndex] = new char[charIndex + 1];
strncpy(words[wordIndex], sentence + len - charIndex, charIndex);
words[wordIndex][charIndex] = '\0';
wordIndex++;
}
wordCount = wordIndex;
}
bool compareWords(const char* word1, const char* word2) {
return strcmp(word1, word2) < 0;
}
void bubbleSort() {
for (int i = 0; i < wordCount - 1; i++) {
for (int j = 0; j < wordCount - i - 1; j++) {
if (compareWords(words[j], words[j + 1])) {
swap(words[j], words[j + 1]);
}
}
}
}
int main() {
cin.getline(sentence, MAX_WORD_LENGTH);
extractWords();
bubbleSort();
cout << wordCount << endl;
for (int i = 0; i < wordCount; i++) {
cout << words[i] << endl;
delete[] words[i];
}
return 0;
}
你的运行结果发出来看看
参考:
怎么会出错呢?按理说该输出0才对。我没有去读strcmp()函数的源码
自己尝试着做了个修改
通过我对字符初始化的方式可以知道,我的两个字符串都没有字符串结束标志
参考资料中给出了strcmp函数的模拟实现,我们可以根据这个代码来理解部分比较为0的原因。首先,通过调用strcmp函数进行字符串比较时,返回值为0表示两个字符串相等。
造成部分比较结果为0的原因可能有以下几种情况: 1. 字符串没有以NULL字符结尾:在段落1中的示例代码中,ch1和ch2字符串没有以NULL字符结尾。由于strcmp是按照ASCII码逐个比较字符,直到遇到NULL字符或者出现不同字符为止。如果字符串没有以NULL字符结尾,则会导致strcmp函数继续比较字符串之后的内存内容,可能会导致比较结果为0。解决这个问题的方法是在字符串后面添加NULL字符。
示例代码:
#include<stdio.h>
#include<string.h>
int main(){
char ch1[3],ch2[3];
ch1[0] = '我';
ch1[1] = '\0';
ch2[0] = '我';
ch2[1] = '\0';
printf("%d",strcmp(ch1,ch2));
return 0;
}
示例代码:
#include <stdio.h>
#include <assert.h>
int my_strcmp(char* str1, char* str2)
{
assert(str1);
assert(str2);
while (*str1 == *str2)
{
if (*str1 == '\0' || *str2 == '\0')
return 0;
str1++;
str2++;
}
return *str1 - *str2;
}
int main()
{
char str1[9] = "abcdefgh";
char str2[7] = "abcdef";
printf("%d\n", my_strcmp(str1, str2));
return 0;
}
如果以上两种情况都没有解决问题,可能是由于其他代码逻辑错误导致的。需要仔细检查代码实现来确定具体原因。