理解这个反向打印句子但保持单词不变的程序



我不太懂这个程序。我不明白for循环中发生了什么。有人能用简单的话向我解释吗。该网站也没有很好地解释这一点。这是指向网站的链接。https://www.geeksforgeeks.org/print-words-string-reverse-order/

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

void printReverse(char str[])
{
int length = strlen(str);
FILE *fptr;
if((fptr=fopen("Question1.txt","w"))==NULL)
{
printf("Invalid file");
exit(0);
}

int i;
for (i = length - 1; i >= 0; i--) {
if (str[i] == ' ') 
{

str[i] = '';

printf("%s ", &(str[i]) + 1);
fprintf(fptr,"%s ", &(str[i]) + 1);
}
}
fprintf(fptr,"%s",str);
printf("%s.", str);
fclose(fptr);
}
int main()
{
char str[1000];
//clrscr();
printf("Enter string: ");
scanf("%[^n]s", str);
printReverse(str);
//getch();
return 0;
}

for循环中,为什么要放&(str[i])+1?而且在printf("%s.", str)中——这只有第一个单词;怎样

好的,让我们看看我是否能帮忙。我会仔细检查代码的。

我怀疑你已经明白了。这只是一个方法调用。

void printReverse(char str[])
{

strlen是一个标准方法,它返回以null结尾的字符串的长度。这意味着str可能包含Hello(5个字符(,但还有一个字节中有一个0,这就是C总是标记字符串末尾的方式。在这种情况下,str本身占用6个字节,但长度为5。

int length = strlen(str);

这就是用C打开文件的方法。C++有更好的方法。该文件是为写入而写的。

FILE *fptr;
if((fptr=fopen("Question1.txt","w"))==NULL)
{
printf("Invalid file");
exit(0);
}

这是你的for循环。假设str包含Hello,所以长度为5,但字符串中的索引为str[0..4]。C使用索引作为"0";"从开始偏移";,所以第一个元素是0,而不是1。因此,当这个循环开始时,str[i]==o(使用Hello作为我们的示例字符串(。然后我们循环,每次递减i。一旦i低于0,循环结束。

int i;
for (i = length - 1; i >= 0; i--) {

记住,我们按正常顺序打印单词,但单词本身的顺序相反。这是在单词之间寻找一个空间。因此,如果我们使用Hello there作为输入文本,当i指向两个单词之间的空格时,这个if语句为true。

下面是诀窍。还记得我前面说过的以null结尾的字符串吗?这样做的目的是踩踏该空间并将其替换为0。这使得这个魔术的其余部分发挥作用。

if (str[i] == ' ') 
{

str[i] = '';

这就是魔术。现在,这是一种奇怪的方式。我本可以用&str[i+1]来做,但这很有效。这是在说";打印在我们刚刚删除的空格之后开始的字符串"我们对终端和文件进行处理。

printf("%s ", &(str[i]) + 1);
fprintf(fptr,"%s ", &(str[i]) + 1);
}
}

这会将生成的重新排列的字符串写入已打开的文件以及您的终端,然后确保文件已关闭。

fprintf(fptr,"%s",str);
printf("%s.", str);
fclose(fptr);
}

这一切之所以有效,是因为我们踩到了零的空间。对于Hello world,我们:

  1. 从尾部开始
  2. 找到空间并在其中加一个零
  3. 打印world
  4. 继续备份到数据末尾
  5. 退出for循环并打印剩下的内容:Hello

回答您的特定问题

在for循环中为什么要放?&(str[i])+1

&str[i]是索引i处的字符地址,其中空格已被NUL字符替换。使用+1,您可以获得后面字符的地址,即刚刚替换的空格后面的单词的开头。(在双空格的情况下,这将导致空字符串。(

而且在printf("%s.", str);中这只有第一个字怎么办?

假设第一个单词前面没有空格,循环将不会打印它。

printf("%s.", str);将从一开始打印字符串,直到第一个NUL字符取代前一个空格字符,从而生成第一个单词。

评论中的其他问题

所以。。。例如,如果我输入Hello World,那么其中的W会得到索引0吗?

W位于索引6处。(H为0,e为1等(

i已经倒计时到5时,该位置的空格将被一个NUL(''(字符替换,并且它将打印从W到同样由NUL字符标记的字符串末尾的剩余字符串。(如C标准所定义。(

如果字符不是NULL字符怎么办?如果对的话,它就不会执行了?它只会再次增加i,直到遇到另一个NULL,对吗?

我不完全理解这些问题。在字符串末尾没有NUL字符的情况下,printf将在字符串末尾读取,从而导致未定义的行为。

在输入字符串Hello World and Universe", all spaces afterWorldwould have been replaced with NUL characters before, so when the program reaches the position of the space beforeWorld的情况下,该字符串将是

Hello WorldandUniverse

更换和之前

HelloWorldandUniverse

更换后。

相关内容

最新更新