gpt4 book ai didi

c - 有没有办法从比 long long int 大的文件中读取数字?

转载 作者:行者123 更新时间:2023-12-02 02:53:24 24 4
gpt4 key购买 nike

我正在尝试读取包含一系列数字的文件

例子:

43917778700000762841090006653470575088202000
43919478100000762851090006653540575088203000
43919765400000815661090006653620575088204000

我的代码:
typedef struct rArc{
long long int code;
}data;

int main(){
long long int code,i=0;
FILE *arc;
data *v;
v = NULL;

arc = fopen("CODES.txt","r");
while(fscanf(arc,"%lld",&code) != EOF){
v = (data *)realloc(v,sizeof(data) * (i + 1));
v[i].code = code;
i++;
}

for(int j=0;j<i;j++){
printf("%lld\n",v[j].code);
}
}

但是因为数字太大,它输出了一些奇怪的随机数。
我想用模数取最后一位数字并添加到 vector 中,但是因为我什至无法阅读它,所以无法按照我尝试的方式进行

更新

我已经设法通过将结构和主代码变量更改为字符代码 [45] 来读取文件,我仍在研究如何进行数学运算,但我想这是一个开始
while(fscanf(arc,"%45s\n",&code) != EOF){
v = (data *)realloc(v,sizeof(data) * (i + 1));
v[i].code = code;
i++;
}

for(int j=0;j<i;j++){
printf("%45s\n",v[j].code);
}
}

最佳答案

即使在评论中进行了 3 次澄清之后,我仍然不完全清楚您的算法,但我相信我对它的理解足以提供帮助。从您对我的评论的回复中,我了解到您想将 10th, 21st & 32nd 字符处的文本替换为通过以下方式获得的值:

  • 对位置左侧的所有字符求和,
  • 通过将每隔一个字符与 2 相乘产生总和,首先将第一个字符乘以 2 ,第二个字符乘以 1 ,第三个字符乘以 2 并继续乘以每个数字的 1-2-1-2-1... 模式,直到达到所需的索引,最后为 2 模式
  • 如果 10 的任何倍数超过 10 ,那么您通过乘积模 sum = sum + (digit * 2-1-multiple) % 10 (例如 10 )来增加总和(或者您可能希望在第 10 个、第 21 个和第 32 个字符的每次替换之前通过 stdin 修改累计总和部分仍不清楚)

  • 既然如此,您可以通过将每个数字字符串读入固定缓冲区来解决问题。 (不要吝啬缓冲区大小)。读取该行后,根据上述模式迭代字符(验证每个是一个数字)并保持运行总和,直到达到所需的索引。在所需的索引处,将原始字符串中的字符替换为该点的总和,并继续直到在第 32 个字符处进行最终索引和替换。

    为此,您可以首先声明缓冲区来保存文件并打开文件(并验证它是否已打开)。您可以将要打开的文件名作为程序的第一个参数,或者如果没有提供参数,则从 2-1-2-1... 中读取,例如
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>

    #define MAXC 512 /* constant for line-buffer size */

    int main (int argc, char **argv) {

    char buf[MAXC] = ""; /* buffer to read each line */
    /* use filename provided as 1st argument (stdin by default) */
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) { /* validate file open for reading */
    fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
    return 1;
    }

    接下来,您将要开始读取循环并声明定位所需位置以插入和所需的变量,这是一种跟踪 '\n' 乘数序列和运行总和的方法。虽然这里不需要(您只能通过第 32 个字符访问,但最好通过 fgets(或 POSIX getline )修剪缓冲区中包含的尾随 #define 作为验证所有字符都适合您的缓冲区的一部分,例如
        while (fgets (buf, MAXC, fp)) {         /* read each line into buf */
    int const pos[] = { 10, 21, 32 }, /* indexes to replace */
    npos = sizeof pos / sizeof *pos; /* no. of indexes */
    int ndx = 0, /* buffer index */
    *pdx = (int *)pos, /* pointer to pos */
    mult = 2; /* 2-1-2-... multiplier */
    size_t len = strlen (buf); /* length of string */
    unsigned sum = 0; /* sum of digits */

    if (len && buf[len - 1] == '\n') /* check for trailing '\n' */
    buf[--len] = 0; /* overwrite with nul-character */
    else if (len == MAXC - 1) { /* otherwise string too long */
    fprintf (stderr, "error: line too long.\n");
    return 1;
    }

    printf ("original: %s\n", buf); /* output the original string */

    一旦您阅读了您的行并验证它是否适合等,您需要遍历字符串中的每个字符,在需要时执行您的总和增量和替换。您还应该验证读取的每个字符都是数字而不是一些杂散的字母字符,或者其他。通过使用作为编译字符串一部分传递的简单预处理器 sum,您可以提供可选的调试输出来帮助您解决算法中的任何问题,例如
            for (; buf[ndx]; ndx++) {           /* iterate over each character */
    if (!isdigit (buf[ndx])) { /* validate character is digit */
    fprintf (stderr, "error: non-digit '%c'.\n", buf[ndx]);
    return 1;
    }
    sum += ((buf[ndx] - '0') * mult) % 10; /* increment sum by % 10 */
    if (ndx + 1 == *pdx) { /* check if ndx+1 is position */
    int ndigit = 0; /* no. of digits in sum */
    char tmp[MAXC] = ""; /* tmp buffer for sum as string */
    ndigit = sprintf (tmp, "%u", sum); /* write sum to tmp */
    #ifdef DEBUG /* debug output */
    printf ("ndx+1: %2d, sum: %3u, ndigits: %d\n",
    ndx+1, sum, ndigit);
    #endif
    if (ndigit) /* validate characters written to tmp */
    memcpy (&buf[ndx], tmp, ndigit); /* copy to buf */
    pdx++; /* increment pos array index */
    if (*pdx == npos) /* check if past last pos index */
    break;
    }
    mult = (mult & 1) ? 2 : 1; /* toggle mult 2-1-2-1... */
    }
    printf ("revised : %s\n\n", buf); /* output updated number in buf */
    }

    总而言之,并添加打开文件的关闭,您可以执行以下操作:
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>

    #define MAXC 512 /* constant for line-buffer size */

    int main (int argc, char **argv) {

    char buf[MAXC] = ""; /* buffer to read each line */
    /* use filename provided as 1st argument (stdin by default) */
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) { /* validate file open for reading */
    fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
    return 1;
    }

    while (fgets (buf, MAXC, fp)) { /* read each line into buf */
    int const pos[] = { 10, 21, 32 }, /* indexes to replace */
    npos = sizeof pos / sizeof *pos; /* no. of indexes */
    int ndx = 0, /* buffer index */
    *pdx = (int *)pos, /* pointer to pos */
    mult = 2; /* 2-1-2-... multiplier */
    size_t len = strlen (buf); /* length of string */
    unsigned sum = 0; /* sum of digits */

    if (len && buf[len - 1] == '\n') /* check for trailing '\n' */
    buf[--len] = 0; /* overwrite with nul-character */
    else if (len == MAXC - 1) { /* otherwise string too long */
    fprintf (stderr, "error: line too long.\n");
    return 1;
    }

    printf ("original: %s\n", buf); /* output the original string */

    for (; buf[ndx]; ndx++) { /* iterate over each character */
    if (!isdigit (buf[ndx])) { /* validate character is digit */
    fprintf (stderr, "error: non-digit '%c'.\n", buf[ndx]);
    return 1;
    }
    sum += ((buf[ndx] - '0') * mult) % 10; /* increment sum by % 10 */
    if (ndx + 1 == *pdx) { /* check if ndx+1 is position */
    int ndigit = 0; /* no. of digits in sum */
    char tmp[MAXC] = ""; /* tmp buffer for sum as string */
    ndigit = sprintf (tmp, "%u", sum); /* write sum to tmp */
    #ifdef DEBUG /* debug output */
    printf ("ndx+1: %2d, sum: %3u, ndigits: %d\n",
    ndx+1, sum, ndigit);
    #endif
    if (ndigit) /* validate characters written to tmp */
    memcpy (&buf[ndx], tmp, ndigit); /* copy to buf */
    pdx++; /* increment pos array index */
    if (*pdx == npos) /* check if past last pos index */
    break;
    }
    mult = (mult & 1) ? 2 : 1; /* toggle mult 2-1-2-1... */
    }
    printf ("revised : %s\n\n", buf); /* output updated number in buf */
    }
    if (fp != stdin) fclose (fp); /* close file if not stdin */

    return 0;
    }

    ( 注意: 上面的算法包括替换值作为下一个替换索引使用的 52 的一部分。即你在第 10 个字符处的替换是第一行的 5。数字 2sum 用作 '\' 的一部分插入第 21 个字符)

    编译时使用 DEBUG 定义 (-DDEBUG)
    $ gcc -Wall -Wextra -pedantic -std=c11 -Ofast -DDEBUG \
    -o bin/str_fill_sum_dbg str_fill_sum.c

    ( 注意: bin line-continuation 用于上面只是为了防止编译字符串滚动超出网页的右边距。此外,我将所有编译的可执行文件放在 bin/ 子目录中,以保持我的源目录干净,您可以省略可执行文件名称的 DEBUG 部分)

    示例调试使用/输出

    调试输出显示索引、插入的该索引处的当前总和以及替换的字符数:
    $ ./bin/str_fill_sum_dbg <dat/sumdigits.txt
    original: 34194716400003108771090006638210572088201000
    ndx+1: 10, sum: 52, ndigits: 2
    ndx+1: 21, sum: 79, ndigits: 2
    ndx+1: 32, sum: 109, ndigits: 3
    revised : 34194716452003108771790006638211092088201000

    original: 34193716400000921121090006638390572088201000
    ndx+1: 10, sum: 50, ndigits: 2
    ndx+1: 21, sum: 68, ndigits: 2
    ndx+1: 32, sum: 104, ndigits: 3
    revised : 34193716450000921121680006638391042088201000

    original: 34191718400000607281090006638470572088201000
    ndx+1: 10, sum: 48, ndigits: 2
    ndx+1: 21, sum: 69, ndigits: 2
    ndx+1: 32, sum: 103, ndigits: 3
    revised : 34191718448000607281690006638471032088201000

    original: 34195718400000550361090006638540572088201000
    ndx+1: 10, sum: 46, ndigits: 2
    ndx+1: 21, sum: 59, ndigits: 2
    ndx+1: 32, sum: 98, ndigits: 2
    revised : 34195718446000550361590006638549872088201000

    original: 34192719900000550361090006638620572088201000
    ndx+1: 10, sum: 51, ndigits: 2
    ndx+1: 21, sum: 64, ndigits: 2
    ndx+1: 32, sum: 95, ndigits: 2
    revised : 34192719951000550361640006638629572088201000

    original: 34198721400000550361090006638700572088201000
    ndx+1: 10, sum: 47, ndigits: 2
    ndx+1: 21, sum: 62, ndigits: 2
    ndx+1: 32, sum: 88, ndigits: 2
    revised : 34198721447000550361620006638708872088201000

    正常编译

    只需删除 modulo 定义的定义以省略调试输出,如果您愿意,可以将可执行文件放在单独的文件名中,这样两者都可用:
    $ gcc -Wall -Wextra -pedantic -std=c11 -Ofast \
    -o bin/str_fill_sum str_fill_sum.c

    示例使用/输出
    $ ./bin/str_fill_sum <dat/sumdigits.txt
    original: 34194716400003108771090006638210572088201000
    revised : 34194716452003108771790006638211092088201000

    original: 34193716400000921121090006638390572088201000
    revised : 34193716450000921121680006638391042088201000

    original: 34191718400000607281090006638470572088201000
    revised : 34191718448000607281690006638471032088201000

    original: 34195718400000550361090006638540572088201000
    revised : 34195718446000550361590006638549872088201000

    original: 34192719900000550361090006638620572088201000
    revised : 34192719951000550361640006638629572088201000

    original: 34198721400000550361090006638700572088201000
    revised : 34198721447000550361620006638708872088201000

    仔细检查一下,如果您还有其他问题,请告诉我。如果您的算法与上面显示的不同,您应该能够轻松地合并任何需要的更改。

    如果10 of Total 插入前

    如果不是对每个数字乘以 2 的结果取模 ojit_code ,而是想在插入前取总和的模,则可以用以下内容替换字符迭代循环:
            for (; buf[ndx]; ndx++) {           /* iterate over each character */
    if (!isdigit (buf[ndx])) { /* validate character is digit */
    fprintf (stderr, "error: non-digit '%c'.\n", buf[ndx]);
    return 1;
    }
    sum += ((buf[ndx] - '0') * mult); /* increment by digit*mult */
    if (ndx + 1 == *pdx) { /* check if ndx+1 is position */
    int replace = sum % 10;
    #ifdef DEBUG /* debug output */
    printf ("ndx+1: %2d, sum: %3u, replace: %d\n",
    ndx+1, sum, replace);
    #endif
    buf[ndx] = replace + '0'; /* replace char at buf[ndx] */
    pdx++; /* increment pos array index */
    if (*pdx == npos) /* check if past last pos index */
    break;
    }
    mult = (mult & 1) ? 2 : 1; /* toggle mult 2-1-2-1... */
    }

    示例调试使用/输出

    在这种情况下,单个字符的替换如下:
    $ ./bin/str_fill_sum_dbg2 <dat/sumdigits.txt
    original: 34194716400003108771090006638210572088201000
    ndx+1: 10, sum: 52, replace: 2
    ndx+1: 21, sum: 95, replace: 5
    ndx+1: 32, sum: 145, replace: 5
    revised : 34194716420003108771590006638215572088201000

    original: 34193716400000921121090006638390572088201000
    ndx+1: 10, sum: 50, replace: 0
    ndx+1: 21, sum: 78, replace: 8
    ndx+1: 32, sum: 145, replace: 5
    revised : 34193716400000921121890006638395572088201000

    original: 34191718400000607281090006638470572088201000
    ndx+1: 10, sum: 48, replace: 8
    ndx+1: 21, sum: 93, replace: 3
    ndx+1: 32, sum: 157, replace: 7
    revised : 34191718480000607281390006638477572088201000

    original: 34195718400000550361090006638540572088201000
    ndx+1: 10, sum: 56, replace: 6
    ndx+1: 21, sum: 87, replace: 7
    ndx+1: 32, sum: 146, replace: 6
    revised : 34195718460000550361790006638546572088201000

    original: 34192719900000550361090006638620572088201000
    ndx+1: 10, sum: 61, replace: 1
    ndx+1: 21, sum: 92, replace: 2
    ndx+1: 32, sum: 148, replace: 8
    revised : 34192719910000550361290006638628572088201000

    original: 34198721400000550361090006638700572088201000
    ndx+1: 10, sum: 57, replace: 7
    ndx+1: 21, sum: 88, replace: 8
    ndx+1: 32, sum: 141, replace: 1
    revised : 34198721470000550361890006638701572088201000

    关于c - 有没有办法从比 long long int 大的文件中读取数字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50862699/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com