【问题标题】:Arbitrary-strings using getline使用 getline 的任意字符串
【发布时间】:2015-12-19 16:05:09
【问题描述】:

所以基本上我的程序在我必须更改它以使其接受任意值之前所做的就是获取 x 数量的单词,并且单词的大小也是任意的。 (两者都是用户输入的)。我通过 multiArray 做到了这一点。 然后按字母顺序排序。

我只是要把它放在那里,因为我的代码很糟糕,而且我对任意字符串和指针的使用非常不熟悉。 I've read up on it in the manual 但我相信这个概念首先需要深入一点。无论如何,我在运行程序时收到错误:“Abort trap: 6”。任何人都可以帮我解决这个问题,以便我可以看到代码在实际工作时的样子,我认为这将帮助我更好地理解指针和分配内存。如果你这样做了,就会永远负债累累。

当前代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_LENGTH 10
int main(){ //8

  char *name;
  char tname[] = {0};
  char temp[] = {0};
  int i=0, j=0, n=0;
  ssize_t bytes_read;
  size_t bytes_number;


  printf("Enter the amount of words you want to input: ");
  scanf("%d", &n);
  printf("Enter %d words: ",n);

  bytes_number = MAX_LENGTH;
  name = (char *) malloc (bytes_number+ 1);
  bytes_number = 0;
  bytes_read = getline(&name, &bytes_number, stdin);

  if (bytes_read == -1){
    puts("ERROR!");
    free(name);
  }

  for (i = 0; i < n; i++){
      strcpy(&tname[i], &name[i]);
  }
  for (i = 0; i < n - 1 ; i++){
      for ( j = i + 1; j < n; j++){
          if (strcmp(&name[i], &name[j]) > 0){
              strcpy(temp, &name[i]);
              strcpy(&name[i], &name[j]);
              strcpy(&name[j], temp);
          }
      }
  }
  printf("\n------------------------------------------\n");
  printf("%-3s %4s %11s\n", "Input","|", "Output");
  printf("------------------------------------------\n");
  for (i = 0; i < n; i++)
  {
      printf("%s\t\t%s\n", &tname[i], &name[i]);
  }
  printf("------------------------------------------\n");
  }

【问题讨论】:

  • 只是puts("ERROR!"); 和 continue 不是正确的错误处理。你为什么投malloc(),编译器会抱怨吗?而且,char tname[] = {0}; 看起来不像你想要的。
  • 程序编译正常,但是在我完成第一个输入阶段后,程序崩溃了。您有什么解决方案吗?
  • 注意:没有-Wall 也能正常编译可能不是真的fine
  • @Joel 你必须重新设计你的程序。您需要存储n 字词。但是你需要考虑: 1.一个词不能超过10个字符,这是你定义的限制。 - 2.您尝试将每个单词复制到同一个变量中(参见iharob的答案);那不是你想要的。 - 3. 你也需要学习 C 中的数组,而不仅仅是指针。

标签: c allocation bubble-sort


【解决方案1】:

这个

strcpy(&tname[i], &name[i]);

完全错了,如果你只是想复制所有的字符,那么它只是

strcpy(tname, name);

相当于

for (size_t i = 0 ; name[i] != '\0' ; ++i)
    tname[i] = name[i];

使用strcpy(&amp;tname[i], &amp;name[i]) 是错误的,因为它会在从第i 个字符开始的每个循环中复制name 中的所有字节,直到找到'\0'

但这会再次失败,因为tname 没有空间,它是一个只有一个元素的数组。

由于您想对字符串进行排序,因此您不需要复制它们。只是交换指针。还有

char temp[] = {0};

只分配1个字符,因此

strcpy(temp, name);

将调用未定义的行为

试试这个,也许这是你需要的

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

int
main(void)
{
    char **words;
    char *temp;
    int word_count;
    int actual_count;
    char *word;
    size_t length;
    int result;

    printf("Enter the amount of words you want to input: ");
    if (scanf("%d%*c", &word_count) != 1)
        return -1; // Input error
    printf("Enter '%d' words:\n", word_count);

    words = NULL;
    word = NULL;
    result = -1;
    actual_count = 0;
    length = 0;
    for (int i = 0 ; i < word_count ; ++i)
    {
        char **pointer;

        printf("Word(%d) > ", i + 1);

        if ((length = getline(&word, &length, stdin)) <= 0)
            goto cleanup;
        // Grow the array of words
        pointer = realloc(words, (i + 1) * sizeof(*pointer));
        if (pointer == NULL)
            goto cleanup; // Memory Exhausted
        // Now it's safe to overwrite `words'
        words = pointer;

        words[i] = malloc(length);
        if (words[i] == NULL)
            goto cleanup; // Memory Exhausted
        memcpy(words[i], word, length);
        words[i][length - 1] = '\0'; // Replace '\n' with '\0'
        actual_count += 1;
    }

    printf("Input : ");
    for (int i = 0 ; i < actual_count ; ++i)
        printf("%s\t", words[i]);
    printf("\n");

    for (int i = 0; i < actual_count - 1 ; i++)
    {
        for (int j = i + 1 ; j < actual_count ; ++j)
        {
            if (strcmp(words[i], words[j]) <= 0)
                continue;
            temp = words[i];
            words[i] = words[j];
            words[j] = temp;
        }
    }

    printf("Output: ");
    for (int i = 0 ; i < actual_count ; ++i)
        printf("%s\t", words[i]);
    printf("\n");

    result = 0;
cleanup:
    free(word);
    for (int i = 0; i < actual_count ; i++)
        free(words[i]);
    free(words);

    return result;
}

注意:这会将空词(完全由空白字符组成)视为有效词。

【讨论】:

  • 嗯。编译器没有抱怨,但我可以看到它为什么不起作用背后的逻辑。正如我所说,我的指针很糟糕......感谢您的反馈。您对我的问题有其他解决方案吗,因为我确定它在分配范围内。
  • 编译器不会抱怨,因为它是有效的语法,但它不正确。
  • 我明白了。我尝试更改我的 strcpy 函数并按照您的建议进行排序。仍然没有运气。该程序应该使用冒泡排序对单词进行排序,并将 A 放在 B 的前面等。
  • 我不需要为此使用数组吗?我还能如何复制整个单词?我只需要使用用户输入分配任意长度字符串的函数。 (在这种情况下为 getline() )。
  • 你程序里的逻辑一点都不清楚,你想干什么?
猜你喜欢
  • 2016-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-24
  • 2021-06-21
  • 2013-03-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多