scanf 函数读入字符串存储至二维数组,访问字符串时非预期结果
我正在编写程序试图颠倒句子中单词的顺序:Enter a sentence: you can cage a swallow can't you?
Reversal of sentence: you can't swallow a cage can you?
我的想法是使用一个二维数组存储单词字符串,通过一个循环使用 scanf 函数读入单词。
每次读入单词时判断单词的最后一个字符是否是终止字符(. ? !)
如果是,则将最后一次读入的单词末尾字符更换为空字符('\0')后结束循环。
然后逆序打印二维数组中的字符串:
#include <stdio.h>
#include <string.h>
#define WORD_NUMBER 30
#define WORD_LENGTH 20
int main(void)
{
char ch, terminator, *p;
char words;
printf("Enter a sentence: ");
p = words;
while (1) {
scanf("%s", p);
// 判断读入字符串的最后一个字符是否是终止符
ch = p;
if (ch == '.' || ch == '?' || ch == '!') {
terminator = ch;
p = '\0';
break;
}
p++;
}
// 逆序打印单词
printf("Reversal of sentence:");
for (; p >= words; p--)
printf(" %s", p);
printf("%c\n", terminator);
return 0;
}
输出的结果并不是如我预期的那样逆序输出单词:
Enter a sentence: you can cage a swallow can't you?
Reversal of sentence: you cyou scyou ascyou cascyou ccascyou yccascyou?
我不理解是什么情况导致了字符串的后缀是 cyou。
拜托各位大佬指点一下错误的地方,感激不尽,谢谢~{:5_100:} 本帖最后由 jhq999 于 2021-12-6 22:26 编辑
#include <stdio.h>
#include <string.h>
#define WORD_NUMBER 30
#define WORD_LENGTH 20
int main(void)
{
char ch, terminator, *p;
char words;
printf("Enter a sentence: ");
p = words;
while (1) {
scanf("%s", p);
// 判断读入字符串的最后一个字符是否是终止符
ch = p;
if (ch == '.' || ch == '?' || ch == '!') {
terminator = ch;
p = '\0';
break;
}
p = '\0';
p+=strlen(p)+1;
}
// 逆序打印单词
printf("Reversal of sentence:");
for (; p >= words; p--)
if(*(p-1)==0||words==p)printf(" %s", p);
printf("%c\n", terminator);
return 0;
} jhq999 发表于 2021-12-6 22:05
输出更乱了:
Enter a sentence: you can cage a swallow can't you?
Reversal of sentence: you 'you n'you an'you can'you ocan'you locan'you llocan'you allocan'you wallocan'you swallocan'you gswallocan'you agswallocan'you cagswallocan'you acagswallocan'you cacagswallocan'you ocacagswallocan'you yocacagswallocan'you?
我的理解是指针 p 自增会移动到二维数组中的下一个一维数组
代码:
p+=strlen(p)-1;
会使指针指向当前单词的末尾字符 wananzuiqingfen 发表于 2021-12-6 22:23
输出更乱了:
我的理解是指针 p 自增会移动到二维数组中的下一个一维数组
没想到要改好几个地方 jhq999 发表于 2021-12-6 22:05
感谢,输出符合预期了,明天研究一下,晚安{:5_100:} 本帖最后由 jhq999 于 2021-12-6 22:41 编辑
#include <stdio.h>
#include <string.h>
#define WORD_NUMBER 30
#define WORD_LENGTH 20
int main(void)
{
char ch, terminator,count=0;
char words;
printf("Enter a sentence: ");
while (1) {
scanf("%s", words);
// 判断读入字符串的最后一个字符是否是终止符
ch =words)-1];
if (ch == '.' || ch == '?' || ch == '!') {
words)-1]='\0';
terminator = ch;
break;
}
count++;
}
// 逆序打印单词
printf("Reversal of sentence:");
for (; count>=0; count--)printf(" %s", words);
printf("%c\n", terminator);
return 0;
} #include <stdio.h>
int main(void)
{
char c , s ;
int i , j , n ;
printf("Enter a sentence : ") ;
gets(s) ;
for(n = 0 ; s ; n = i) {
for(; s && s < 0x21 ; n ++) ;
for(i = n ; s && s > 0x20 ; i ++) ;
for(j = 0 ; j < (i - n) / 2 ; j ++) {
c = s ;
s = s ;
s = c ;
}
}
for(i = 0 ; i < n / 2 ; i ++) {
c = s ;
s = s ;
s = c ;
}
printf("Reversal of sentence : %s\n" , s) ;
}
编译、运行实况:
D:\00.Excise\C>g++ -o x x.c
D:\00.Excise\C>x
Enter a sentence : you can cage a swallow can't you?
Reversal of sentence : you? can't swallow a cage can you
D:\00.Excise\C> {:10_254:} 错误之处在于对指针的运用,指针 p 初始指向了二维数组的第一个元素(一个一维数组,实际就是指向了这个一维数组的第一个元素)。
语句:
p++;将二维数组展开看成是一个一维数组,它们的内存地址是连续的,且由于 p 不是指向数组的指针,因此 p++; 只是简单的移动到了下一个内存地址上,这也是造成错误的根源。{:5_100:}{:5_100:}{:5_100:}
改进后的程序如下:
#include <stdio.h>
#include <string.h>
#define WORD_NUMBER 30
#define WORD_LENGTH 20
int main(void)
{
char ch, terminator, *p;
char words;
printf("Enter a sentence: ");
p = words;
while (1) {
scanf("%s", p);
// 判断读入字符串的最后一个字符是否是终止符
ch = p;
if (ch == '.' || ch == '?' || ch == '!') {
terminator = ch;
p = '\0';
break;
}
p += WORD_LENGTH;
}
// 逆序打印单词
printf("Reversal of sentence:");
for (; p >= words; p -= WORD_LENGTH)
printf(" %s", p);
printf("%c\n", terminator);
return 0;
}
jackz007 发表于 2021-12-6 22:40
编译、运行实况:
大师{:5_100:}{:5_100:}{:5_100:} {:10_256:} 1 {:10_254:} {:10_254:} 萌新学习,谢谢大佬,大佬真好! 感谢分享! {:10_264:} 强
页:
[1]