【问题标题】:shifting elements in an array of strings and fill with zeros移动字符串数组中的元素并用零填充
【发布时间】:2015-03-22 15:01:55
【问题描述】:

我想将数组中的元素向右移动,并用零(作为字符串)填充移动的元素。但这比我想象的要难。

这个程序读取一个包含两行的文本文件。每行包含一个整数(定义了最大长度)。它将每一行保存在一个单独的数组中。

稍后我需要将这两个数组转换为整数数组并进行一些算术运算。

为此,我需要确保这两个数组的长度相同

例如我的输入是:

num_first : 1859654

num_second:5654

现在我需要它们:

num_First : 1859654(它大于第二个数字所以它不会改变)

num second:0005654(小于第一个,所以我们需要添加那些前导零

如何根据两个输入的差异将前导零添加到数组中??

最后我想将它们保存在数组中(作为字符串或整数)。

#include <stdio.h>
#include <string.h>
#define SIZE_MAX 20

int main()
{

FILE *fPTR;

    char num_first[SIZE_MAX]; // string input
    char num_second[SIZE_MAX];

    if ((fPTR = fopen("input.txt", "r")) == NULL) // our file contains two line of integers. one at each
    {
        puts("File could not be opened.");
    }
    else
    {
        if (fgets(num_first, SIZE_MAX, fPTR) != NULL) // reads first line and saves to num_first
            puts(num_first); // prints first number
        if (fgets(num_second, SIZE_MAX, fPTR) != NULL) // reads second line and saves to num_second
            puts(num_second); // prints second number
        fclose(fPTR);
    }

    // getting strings lengths
    int fLEN = strlen(num_first) - 1;
    int sLEN = strlen(num_second);


    int e = 0; // difference between two string lengths

    // here we get the difference and it's the place which i want to shif the arrays

    if (fLEN>sLEN) // first string is bigger than second
    {
        e = fLEN-sLEN;
    }
    else if (sLEN>fLEN) // second string is bigger than first
    {
        e = sLEN-fLEN;
    }
    else // there is no difference between two strings
    {
        e = fLEN-sLEN;
    }

}

编辑:我也有另一个想法,但它没有按预期工作。

if (fLEN>sLEN) // first string is bigger than second
    {
        e = fLEN-sLEN;
        for(i=e;i>=0;i--)
        {
            num_second[i+1] = num_second[i];
        }
        for(i=fLEN-e;i>=0;i--)
        {
            num_second[i] = '0';
        }
    }

edit 2:(慢慢开始工作)打印更多零。试图修复它

    #include <stdio.h>
#include <string.h>
#define SIZE_MAX 20

int main()
{

FILE *fPTR;

    char num_first[SIZE_MAX]; // string input
    char num_second[SIZE_MAX];
    char num_second2[SIZE_MAX] = {0};
    int i = 0;
    char numbers[SIZE_MAX];

    if ((fPTR = fopen("input.txt", "r")) == NULL) // our file contains two line of integers. one at each
    {
        puts("File could not be opened.");
    }
    else
    {
        if (fgets(num_first, SIZE_MAX, fPTR) != NULL) // reads first line and saves to num_first
            puts(num_first); // prints first number
        if (fgets(num_second, SIZE_MAX, fPTR) != NULL) // reads second line and saves to num_second
            puts(num_second); // prints second number
        fclose(fPTR);
    }

    // getting strings lengths
    int fLEN = strlen(num_first) - 1;
    int sLEN = strlen(num_second);


    int e = 0; // difference between two string lengths
    int h = 4;

    // here we get the difference and it's the place which i want to shif the arrays

    if (fLEN>sLEN) // first string is bigger than second
    {
        e = fLEN-sLEN;
        while (i>= h)//for(i=e;i>=0;i--)
        {
            num_second2[i+h] = num_second[i];
            i++;
            h--;
        }
        for(i=fLEN-e;i>=0;i--)
        {
        //  num_second[i] = '0';
        }
    }
    else if (sLEN>fLEN) // second string is bigger than first
    {
        e = sLEN-fLEN;
    }
    else // there is no difference between two strings
    {
        e = fLEN-sLEN;
    }
    printf("\n%d\n", e);
        for (i = 0; i < SIZE_MAX; i++) // using c to print
    {
        printf("%d", num_second2[i]);
    }
    puts(num_second);
}

【问题讨论】:

  • 那么你的问题是什么?除非您提供明确的问题,否则您可以自己完成其余的工作。
  • 已编辑。我想根据输入数字的差异添加那些前导零。
  • strcatsprintf 可能对你有用
  • 如果您能提供解决方案并在代码中使用它然后分享它,我们将不胜感激。我也不想打印任何东西。我只想添加前导零然后保存到数组。
  • @vvvsg 在 C 中,char 或字符串数​​组几乎相同,在您的情况下也非常相似。我发表评论的目的是帮助您自己解决问题,而不是提供对您帮助较少的直接答案。

标签: c arrays


【解决方案1】:
#include <stdio.h>
#include <string.h>
#define SIZE_MAX 20

int main()
{

    FILE *fPTR;

    char num_first[SIZE_MAX]; // string input
    char num_second[SIZE_MAX];
    char num_zeros[SIZE_MAX];//array for leading zeros
    int i = 0;
    char numbers[SIZE_MAX];

    if ((fPTR = fopen("input.txt", "r")) == NULL) // our file contains two line of integers. one at each
    {
        puts("File could not be opened.");
    }
    else
    {
        if (fgets(num_first, SIZE_MAX, fPTR) != NULL) // reads first line and saves to num_first
            puts(num_first); // prints first number
        if (fgets(num_second, SIZE_MAX, fPTR) != NULL) // reads second line and saves to num_second
            puts(num_second); // prints second number
        fclose(fPTR);
    }
    for ( i = 0; i < SIZE_MAX; i++)
    {
        num_zeros[i] = '0';//fill array with '0's
    }
    // getting strings lengths
    int fLEN = strlen(num_first);
    if ( fLEN && num_first[fLEN - 1] == '\n')
    {
        num_first[fLEN - 1] = '\0';//remove trailing newline
        fLEN--;
    }
    int sLEN = strlen(num_second);
    if ( sLEN && num_second[sLEN - 1] == '\n')
    {
        num_second[sLEN - 1] = '\0';//remove trailing newline
        sLEN--;
    }
    int e = 0; // difference between two string lengths
    // here we get the difference and it's the place which i want to shif the arrays
    if (fLEN>sLEN) // first string is bigger than second
    {
        e = fLEN-sLEN;
        num_zeros[e] = '\0';//terminate array leaving e leading zeros
        strcat ( num_zeros, num_second);
        strcpy ( num_second, num_zeros);
    }
    else if (sLEN>fLEN) // second string is bigger than first
    {
        e = sLEN-fLEN;
        while ( fLEN >= 0)//start at end of array
        {
            num_first[fLEN + e] = num_first[fLEN];//copy each element e items from current location
            fLEN--;// decrement length
        }
        while ( e)// number of leading zeros
        {
            e--;
            num_first[e] = '0';// set first e elements to '0'
        }
    }
    else // there is no difference between two strings
    {
        //e = fLEN-sLEN;
    }
    puts(num_first);
    puts(num_second);
    return 0;
}

【讨论】:

    【解决方案2】:

    从您的代码开始。

    由于您正在读取字符串,因此您可以使用字符串操作。 如果您想将它们读取为整数,您可以使用对数函数来确定大小,但这将是矫枉过正。

    可以将数字保存为整数,但是您必须推迟填充,直到您稍后打印它们或将它们保存到文件中。

    用零填充数字的最简单方法是使用带有正确格式说明符的 sprintf() 来右对齐数字。 然后您可以遍历结果的每个字符并替换空格,例如' ' 与 '0'。这将创建左侧 0 填充条目。例如。 sprintf right 在缓冲区中证明您的数字是合理的,该缓冲区有空间容纳您可以读取的最大数字,在左侧留下空格。

    然后在一个循环中,在条目中一次索引一个字符,并根据下面显示的 MAX_NUMBER_LEN,跳过左边的多余空格(例如 MAX_NUMBER_LEN - maxPaddingLenYouCalculateAtRuntime),并开始用零替换.

    然后,只需创建一个缓冲区,您将把它的地址传递给 sprintf(),该缓冲区有足够的空间来保存结果。这必须与您的最大长度一样大或更大。我将其称为 maxStrLen 而不是 e,因为根据变量的用途命名变量可以更容易理解和维护程序。

    对于如何分配正确大小的缓冲区,您有几个选择,包括使用 malloc()。但是确定整数的最大大小可能更容易。甚至还有一个 C 常量可以告诉您最大 32 位或 64 位整数是多少。值是,并预先根据该大小创建一个固定长度条目的 char 数组。

    例如:

    #define MAX_ENTRIES = 10
    #define MAX_NUMBER_LEN = 15
    char numbers[MAX_ENTRIES][MAX_NUMBER_LEN]
    

    这将为您提供存储 sprintf() 结果的存储空间。 示例:

    sprintf(numbers[entryNumber], "*right-justifying format specifier you look up*", numberReadFromFile)
    

    其中 entryNumber 是要存储结果的数组中的哪个槽。

    在获取 sprintf 的地址时不需要包含的 MAX_NUMBER_LEN 部分(请注意,我只是故意传入了 numbers[entryNumber],而不是第二组括号)。因为通过省略第二组括号,您是说您想要在 numbers 数组中与 entryNumber 对应的特定 [MAX_NUMBER_LEN] 块的地址。请注意,numberReadFromFile 上也没有 &,因为您将它们作为字符串读入 char array,并且因为您传递的是第一个字符的地址数组你可以只传递数组名称。或者,您可以传入 &numberReadFromFile[0] 以获取要传递给 sprintf() 的第一个元素的地址。

    当使用数组 的方式时,你不需要 & 字符来获取传递给 sprintf() 的变量地址,如果你是不传入数组元素,因为数组实际上只是 C 中 pointers 的另一种 表示法,理解它的一般工作原理是在一般情况下有效使用 C 的关键并且值得最初的努力去理解。

    这里有一个示例,说明如何根据您从 sprintf 进入数组的内容进行实际的零填充。我不会编写一个完整的例子,因为学习 C 是关于自己实际做的斗争。真正的理解没有捷径可走。我给你最难发现的方面,通过你解决它并解决它,你将获得相当多的掌握。这段代码不在我的脑海中,没有经过编译和测试。它要么工作要么接近工作。

    /* numberToPad is a buffer containing a right-justified number, e.g. a number
     * shifted-right by sprintf(), in a buffer sized 15 characters,
     * space-padded on the left by sprintf's right-justifying format specifier.       
     * We want to convert the number to a 10-digit zero-padded number
     * inside a 15 character field. The result should be 4 spaces, followed
     * by some zeroes, followed by non-zero digits, followed by null-terminator.
     * example: "ƀƀƀƀ0000012345\0" where ƀ is a space character.
     */
    
    #define MAX_NUMBER_LEN 15  /* note: 15 includes null-terminator of string */
    int maxNumberLenActuallyRead = 10;
    int startZeroPaddingPos = MAX_NUMBER_LEN - maxNumberLenActuallyRead
    char numberToPad[MAX_NUMBER_LEN]; 
    int i;
    for (i = 0; i < MAX_NUMBER_LEN; i++) {
        if (i < startZeroPaddingPos) 
            continue;
        if (numberToPad[i] == ' ')
            numberToPad[i] = '0';         
    }
    

    【讨论】:

    • 谢谢。几个问题: 1- numbers[entryNumber] 是存储结果的数组吗? 2-我究竟如何使用右对齐和填充零?一个工作完整的代码就可以完成这项工作。谢谢编辑:在定义中也不应该有 = 符号
    • 我一直在编辑它,但我现在已经完成了。来吧,问问题。我会继续检查并尽力提供帮助。
    • 1.是的。 2. 你需要一个 for 循环遍历 char 的每个字符,但将其与 ' '(空格)进行比较并替换 some w/'0'。我说一些是因为您可能使数组 [MAX_NUMBER_SIZE] 字段 wider 比您实际想要用零填充。因为它是在编译时选择数组大小,但实际填充大小取决于您实际读取的数字的最大大小。 3. #define 是一个编译时预处理指令,用于定义常量,而不是变量,并且不使用'='。我将折腾一个小例子来说明如何遍历一个 char 数组。
    • @1sand0s 请注意,有一个 printf 说明符可以用 '0' 填充
    • 如果您将数字转换为 int 可能有,我知道如何为浮点数执行此操作,不知道如何用零填充数字。在 sprintf() 格式说明符选项中寻找这将是一件好事。
    猜你喜欢
    • 1970-01-01
    • 2010-09-24
    • 1970-01-01
    • 2023-01-31
    • 2018-11-14
    • 2019-04-11
    • 2022-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多