更改字符串中某些单词的顺序

Changing the order of some words in a string

我已经尝试解决这个练习一个星期了,但我的代码不起作用,我不明白为什么以及如何更改它。练习是: 从用户那里接收一个长度,然后接收一个字符串 (str) 只要 'length' 然后从 user.Then 接收一个数字 (int n) 我需要执行函数 'void ReverseNumWords (char* str, int n). 该函数反转字符串中的前 n 个单词。例如:对于 'I am your father StarWars' 和 n=3: 'your am I father StarWars'。假设单词由 ' ' 分隔是正确的。谢谢您的帮助!!

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

void Reverse()
{

   int len,num;
   char *str;
   printf("Please enter how many chars to allocate:\n");
   //Asking from the user the length of a string.
   scanf("%d", &len);
   //Allocating memory for the string.
   str = (char*)calloc(len, sizeof(int));
   //Making sure the allocation was successful.
   if (!str)
       printf("Error: Cannot allocate Memory\n");
   printf("Allocated %d chars\n", len);
   printf("Please enter your string:\n");
   scanf("%s", str);
   printf("Please enter how many words to reverse:\n");
   scanf("%d", &num);
   ReverseNumWords(*str, num, len);
   free(str);
}

void ReverseNumWords(char*str, int num,int len)
{

   char *sub;
   char temp;
   //Allocating memory for the string.
   sub = (char*)calloc(len, sizeof(int));
   //Making sure the allocation was successful.
   if (!sub)
       printf("Error: Cannot allocate Memory\n");
   int i, j,l;
   i = j = 0;
   for (; i < len, j <= num; i++)
       if (str[i] == '[=10=]' || str[i] == 0)
           j++;

   for (l = 0; l < i; l++)
       sub[i] = str[i];

   for (j = 0; j < i; j++)
       temp = sub[j];
       sub[j] = sub[i - (1+j)];
       sub[i - (1+j)] = sub[j];

   reverseWords(*sub);


}

void reverseWords(char *sub)
{

   char *word_begin = sub;
   char *temp = sub;

   while (*temp)
   {
      temp++;
      if (*temp == '[=10=]')
      {
         reverse(word_begin, temp - 1);
      }
      else if (*temp == ' ')
      {
         reverse(word_begin, temp - 1);
         word_begin = temp + 1;
      }
   } 

   reverse(sub, temp - 1);
}

void reverse(char *begin, char*sub, char *end)
{

    char temp;
    while (begin < end)
    {
        temp = *begin;
        *begin++ = *end;
        *end-- = temp;
    }
    printf("%s\n", sub);
}

你的读取函数,应该是这样的

int len,num;
   char *str;
   printf("Please enter how many chars to allocate:\n");
   //Asking from the user the length of a string.
   scanf(" %d", &len);
   //Allocating memory for the string.
   str = (char*)malloc(sizeof(char)*(len+1));
   //Making sure the allocation was successful.
   if (!str)
       printf("Error: Cannot allocate Memory\n");

   printf("Allocated %d chars\n", len);
   printf("Please enter your string:\n");
   scanf(" %[^\n]s", str);

   printf("Please enter how many words to reverse:\n");
   scanf(" %d", &num);
   ReverseNumWords(*str, num, len);
   free(str);

因为使用 %s 阅读时,您会在找到的第一个“ ”(空白 space)处停止。并且您想阅读直到找到 \n(输入)。

这一行:

str = (char*)calloc(len, sizeof(int));

这需要:

str = (char*)calloc(len, sizeof(char));

我还建议您使用 malloc 为您的字符串分配内存,因为您似乎无法使用 calloc()

你会像这样使用它:

char *str = malloc(len+1); /* Since sizeof(char) is 1, you don't need to include it */

这也说明了您 Don't need to cast the result of malloc().

很高兴看到您检查了分配的 return 值, 总是一件好事。

另一种读取字符串的方法:

您可以使用 fgets 而不是使用 scanf()stdin 读取字符串。

char *fgets(char *str, int n, FILE *stream) reads a line from an input stream, and copies the bytes over to char *str, which must be given a size of n bytes as a threshold of space it can occupy.

fgets注意事项:

  • 在缓冲区末尾追加 \n 个字符。如果您愿意,可以轻松移除。
  • 出错,returns NULL。如果没有读取字符,最后还是returns NULL
  • 缓冲区的大小必须为n
  • 读取指定流。来自 stdinFILE *

这是一个示例,说明如何使用它从 stdin 读取一行输入:

char buffer[100]; /* statically declared buffer */

printf("Enter a string: ");
fgets(buffer, 100, stdin); /* read line of input into buffer. Needs error checking */

您还可以使用 strtok and strcat 等函数来反转和连接您的字符串。

这是一个在字符串中包含 n 个单词的示例程序:

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

char *allocate_chars(int *len);
void number_of_words(int *num);
void read_strings(char *str, int len);
char *reversed_words(char *str, int len, int num);
char *reverse_word(char *word);

int main(void) {
    int len, num;
    char *str, *result;

    str = allocate_chars(&len);

    read_strings(str, len);

    number_of_words(&num);

    result = reversed_words(str, len, num);
    printf("Reversed string = %s\n", result);

    free(result);
    free(str);

    return 0;
}

char *allocate_chars(int *len) {
    char *str;

    printf("Enter how many chars to allocate: ");
    if (scanf("%d", len) != 1 || *len < 1) {
        printf("Invalid length.\n");
        exit(EXIT_FAILURE);
    }
    getchar();

    str = malloc(*len+1);
    if (!str) {
        printf("Cannot allocate %d bytes for string.\n", *len+1);
        exit(EXIT_FAILURE);
    }

    printf("Allocated %d chars.\n", *len+1);

    return str;
}

void number_of_words(int *num) {
    printf("Please enter how many words to reverse: ");
    if (scanf("%d", num) != 1 || *num < 0) {
        printf("Invalid number.\n");
        exit(EXIT_FAILURE);
    }
}

void read_strings(char *str, int len) {
    int slen;

    printf("Please enter your string: ");
    if (fgets(str, len, stdin) == NULL) {
        printf("Cannot create buffer.\n");
        exit(EXIT_FAILURE);
    }

    slen = strlen(str);
    if (slen > 0) {
        if (str[slen-1] == '\n') {
            str[slen-1] = '[=14=]';
        } else {
            printf("Entered string bigger than buffer size of %d bytes.\n", len);
            exit(EXIT_FAILURE);
        }
    }

    if (!*str) {
        printf("No string entered.\n");
        exit(EXIT_FAILURE);
    }
}

char *reversed_words(char *str, int len, int num) {
    char *reversed, *word, *reversed_word;
    const char *delim = " ";
    int count = 1;

    reversed = malloc(len+1);
    if (!reversed) {
        printf("Cannot allocate %d bytes for string.\n", len+1);
        exit(EXIT_FAILURE);
    }

    *reversed = '[=14=]';

    word = strtok(str, delim);
    while (word != NULL) {
        if (count <= num) {
            reversed_word = reverse_word(word);
            strcat(reversed, reversed_word);
            free(reversed_word);
            count++;
        } else {
            strcat(reversed, word);
        }
        word = strtok(NULL, delim);
        if (word != NULL) {
            strcat(reversed, delim);
        }
    }

    return reversed;
}

char *reverse_word(char *word) {
    char *reverse;
    int slen, str_count = 0, i;

    slen = strlen(word);

    reverse = malloc(slen+1);
    if (!reverse) {
        printf("Cannot allocate %d bytes for string.\n", slen+1);
        exit(EXIT_FAILURE);
    }

    for (i = slen-1; i >= 0; i--) {
        reverse[str_count++] = word[i];
    }
    reverse[str_count] = '[=14=]';

    return reverse;
}

示例输入:

Enter how many chars to allocate: 50
Allocated 51 chars.
Please enter your string: Hello what a lovely day
Please enter how many words to reverse: 4

输出:

Reversed string = olleH tahw a ylevol day