【问题标题】:how to manipulate char array in C如何在C中操作char数组
【发布时间】:2020-04-14 23:35:07
【问题描述】:

我正在练习学习 C 并创建程序,其中用户输入一个 int,然后输入多个名字和姓氏。然后程序将打印所有名字姓氏名字。我试图在以前的帖子中找到这个问题,例如this,但找不到我的问题的好答案。 例如,

输入:

2

杰克·琼斯

米拉咕

输出:

琼斯·杰克

古米拉

相反,我的程序会打印出行话:

����4LJo �5Lne Jack

去迈拉

下面是我的代码:

#include <stdio.h>
#include <string.h>
int main(void) {
    //! word1 = showArray(word1, cursors=[i], width=0.5)
    //! word2 = showArray(word2, cursors=[i], width=0.5)
    int num;
    //char word2[8];
    int count = 0;
    char first[101];
    char last[101];
    char all[1000];
    int last_letter_of_all;
    
    scanf("%i", &num);
    while(count != num){
        
        scanf("%s %s", first, last);
        int len_first = strlen(first);
        int len_last = strlen(last);
        //printf("%i %i\n", len_first, len_last);
        
        //add letters of last
        for(int k = 0; k < len_last; k++)
        {
            last_letter_of_all = strlen(all);
            char c = last[k];
            all[last_letter_of_all] = c;
           // printf("%c\n", c);
        }
        
        //find last location of last name added
        all[last_letter_of_all] = ' ';
        
        //add first name 
        for(int l = 0; l < len_first; l++)
        {
            last_letter_of_all = strlen(all);
            char c = first[l];
            all[last_letter_of_all] = c;
        }
       
        
        //find last space of location
        all[last_letter_of_all+1] = '.';
        count++;
    }
    
    for(int i = 0; i < strlen(all); i++)
    {
        if(all[i] != '.')
        {
         printf("%c", all[i]);
        }
        else
        {
            printf("\n");
        }
    }
   
    return 0;
}

我已经为此苦苦挣扎了一段时间。我来自 Java,对 C 很陌生,但我相信这可能与表示数组结束的“/0”有关。

【问题讨论】:

  • 请注意,当您第一次调用 strlen(all) 时,all 是未初始化的。

标签: c arrays sorting char


【解决方案1】:

您应该使用结构来表示单个名字-姓氏对。然后你有一个这些结构的数组来保存名称。您使用malloc 而不是常规的数组语法分配数组,因为您不知道数组有多大。然后填充数组的条目。

数组填充后,这次遍历数组,使用 printf 打印每个条目,但姓氏在前,名字在后。

(省略错误检查)

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

typedef struct {
    char first[101], last[101];
} name;

int main()
{
    int num;
    name *arr;
    int i;

    puts("How many names?");
    scanf("%d", &num);

    arr = malloc(num * sizeof(name));

    /* populate entries of the array */
    puts("Enter [first last] names");
    for (i = 0; i < num; ++i)
        scanf("%100s %100s", arr[i].first, arr[i].last);

    /* print each entry, but with last name first and first name last */
    for (i = 0; i < num; ++i)
        printf("%s %s\n", arr[i].last, arr[i].first);

    free(arr);
    return 0;
}

附带说明一下,在%s 中为scanf 包含缓冲区的最大宽度总是一个好主意。

【讨论】:

  • 此代码包含潜在的缓冲区溢出:由于您没有告诉 scanf() 数组 firstlast 的长度,所以当用户输入的名称是超过 100 个字符。您可以更改格式字符串以将大小限制为缓冲区的大小,但更好的是使用%ms 转换让scanf() 为您分配缓冲区;这样可以避免缓冲区溢出 并且 它适用于任意长度的名称。不过,您确实需要确保稍后释放分配的内存。
  • 我知道。这就是为什么我说省略了错误处理。另外,据我所知,%ms 是非标准的@G.Sliepen
  • 不做错误处理(比如检查scanf()的返回值)和完全错误的代码之间是有区别的,这些代码会根据输入而崩溃。 %ms 在 POSIX.2008 标准中,但在 C99 中确实没有。
  • 我做到了,但我看到你知道修复了缓冲区溢出,太棒了!所以我把它改成了赞成票。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-01
  • 1970-01-01
相关资源
最近更新 更多