移动字符串数组中的元素并用零填充

时间:2015-03-22 15:01:56

标签: c arrays

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

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

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

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

例如我的输入是:

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';
        }
    }

编辑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);
}

2 个答案:

答案 0 :(得分:3)

#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;
}

答案 1 :(得分:1)

您的代码良好开端。

由于你正在阅读字符串,你可以使用字符串操作。 如果你想把它们作为整数读出来,你可以用对数函数来确定它的大小,但这样就太过分了。

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

使用零填充数字的最简单方法是使用具有正确格式说明符的sprintf()来右对齐数字。 然后您可以遍历结果的每个字符并替换空格,例如&#39; &#39;用&#39; 0 &#39;。这将创建左侧0填充条目。例如。 sprintf右边在一个缓冲区中证明你的号码,缓冲区有空间可以容纳你可以读取的最大大小的数字,左边留有空格。

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

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

您可以选择如何分配正确大小的缓冲区,包括使用malloc()。但是,确定整数的最大大小可能更容易。甚至还有一个C常量可以告诉你32位或64位整数最大值。 value是,并且事先根据该大小创建一个固定长度条目的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部分需要包含(注意我刚刚传入了数字[entryNumber],而不是第二组括号,故意)。因为省略了第二组括号,所以你想要在数字数组中想要与entryNumber对应的特定[MAX_NUMBER_LEN]块的地址。请注意,numberReadFromFile上没有&amp; ,因为您将它们作为字符串读入char 数组,并且因为您正在传递第一个地址数组的char,你可以传递数组名称。或者,您可以传入&amp; numberReadFromFile [0]以获取要传递给sprintf()的第一个元素的地址。

当使用 方式的数组时,你不需要&amp; 字符来获取变量地址以传递给sprintf(),就像你想的那样如果你没有传入一个数组元素,因为数组实际上只是C中指针的另一个符号,并且了解它的工作方式通常是有效的关键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';         
}