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

时间:2017-01-08 15:36:47

标签: c string pointers malloc calloc

我一直在尝试解决此练习一周,而且我的代码不起作用,我无法理解为什么以及如何更改它。练习是: 从用户那里收到一个长度,然后收到一个字符串(str),只要长度为'然后从用户那里接收一个数字(int n)。然后我需要执行函数' void ReverseNumWords(char * str,int n)。该函数反转字符串中的前n个单词。例如:因为我是你父亲的星球大战'并且n = 3: '你是我父亲的星球大战'。假设单词被'分开是正确的。 &#39 ;.谢谢您的帮助!!

state.mystateproperty

2 个答案:

答案 0 :(得分:1)

您的阅读功能应该是这样的

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进行阅读时,您将停在您找到的第一个“空白处”。你想要阅读,直到找到\ n(输入)。

答案 1 :(得分:0)

在这一行:

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()

这一事实

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

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

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

  

char *fgets(char *str, int n, FILE *stream)从输入流中读取一行,并将字节复制到char *str,其大小必须为n个字节,作为它可占用的空间阈值。

有关fgets的注意事项:

  • 在缓冲区末尾添加\n个字符。如果您愿意,可以轻松删除。
  • 出错时,返回NULL。如果没有读取任何字符,最后仍会返回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 */

您还可以使用strtokstrcat等函数来反转和连接字符串。

以下是字符串中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] = '\0';
        } 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 = '\0';

    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] = '\0';

    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