gpt4 book ai didi

c - 读取文件,并从临时变量创建字符串数组

转载 作者:行者123 更新时间:2023-11-30 14:52:02 25 4
gpt4 key购买 nike

最终目标是从文件创建字符串数组。所以我有一个文件,我需要从 temp1、temp2、temp3 等获取临时变量。我不会提前知道有多少。我的第一个想法是使用 strcat 从我找到的变量创建一个普通字符串,然后使用标记拆分它。我想我可以通过正常添加字符串来绕过这个问题。

while(feof(inputFile))
{
fscanf(inputFile, " %s ", readIn);

if(strcmp("AND", readIn) == 0 || strcmp("OR", readIn) == 0 || strcmp("NAND", readIn) == 0 || strcmp("NOR", readIn) == 0 || strcmp("XOR", readIn) == 0)
{
fscanf(inputFile, "%s ", readIn);
fscanf(inputFile, "%s ", readIn);
fscanf(inputFile, "%s ", tempVar);
//printf("the char is %c", tempVar[0]);

//check to see if its a temp variable since temps are always lower case
if(tempVar[0] == 't')
{
numVars++;
tempHeaders = realloc(tempHeaders, sizeof(char*) * numVars);
int temp = numVars -1;
printf("the variable is %s and the number is %d\n", tempVar, temp);
tempHeaders[numVars - 1] = tempVar;
}

numGates++;
}
}

此时变量的数量是正确的,问题在于添加到数组 tempHeaders 时。数组的整个值将是文件的最后一个字是什么,即如果最后一个字已经出来。 tempHeaders i - n 都会消失。有任何想法吗?谢谢

我已经从 while 循环中删除了 feof 并更改为“while(fscanf(inputFile, "%s ", readIn) != EOF){”

示例输入为

OR IN1 IN2 temp1
OR IN3 IN4 temp2
OR IN5 IN6 temp3
OR IN7 IN8 temp4
AND temp1 temp2 temp5
AND temp3 temp4 temp6
XOR temp2 temp6 OUT1

此时的示例输出

the variable is temp1 and the number is 0
the variable is temp2 and the number is 1
the variable is temp3 and the number is 2
the variable is temp4 and the number is 3
the variable is temp5 and the number is 4
the variable is temp6 and the number is 5
Printing OUT1
Printing OUT1
Printing OUT1
Printing OUT1
Printing OUT1
Printing OUT1
numGates = 7, numVars = 6

打印内容应该是 temp1、temp2、temp3 等...

最佳答案

我制作了一个工作示例来完成我认为您打算做的事情:

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

char* strdup(const char *str)
{
int len = strlen(str);
char *str2 = malloc((len + 1) * sizeof (char));
if (str2) strcpy(str2, str);
return str2;
}

int main()
{
FILE *f = stdin;
/** @todo evaluation of command line arguments could
* check whether input file given
* and in that case override f with fopen().
*/
/* read input */
if (!f) {
fprintf(stderr, "ERROR: Cannot read input!\n");
return 1;
}
int nGates = 0, nVars = 0;
char **vars = NULL;
char buffer[80];
for (int iLine = 1; fgets(buffer, sizeof buffer, f); ++iLine) {
char *op = strtok(buffer, " \t\r\n");
if (!op
|| strcmp(op, "AND") != 0 && strcmp(op, "OR") != 0 && strcmp(op, "XOR") != 0
&& strcmp(op, "NAND") != 0 && strcmp(op, "NOR") != 0) {
fprintf(stderr, "ERROR in line %d: OP expected!\n", iLine);
continue;
}
char *var;
while (var = strtok(NULL, " \t\r\n")) {
if (var[0] == 't') {
++nVars;
vars = realloc(vars, sizeof (char*) * nVars);
if (!vars) {
fprintf(stderr, "ERROR: Out of memory!\n");
return 1;
}
int iVar = nVars - 1;
vars[iVar] = strdup(var);
if (!vars[iVar]) {
fprintf(stderr, "ERROR: Out of memory!\n");
return 1;
}
printf("Var. #%d: '%s'\n", iVar, var);
}
}
++nGates;
}
/* evaluate input */
printf("Report:\n");
printf("nGates: %d, nVars: %d\n", nGates, nVars);
for (int i = 0; i < nVars; ++i) {
printf("vars[%d]: '%s'\n", i, vars[i]);
}
/* done */
return 0;
}

我在 cygwin 上的 bash 中测试了代码(在 Windows 10 上):

$ gcc --version
gcc (GCC) 6.4.0

$ gcc -std=c11 -o testStrtok testStrtok.c

$ ./testStrtok <<'EOF'
OR IN1 IN2 temp1
OR IN3 IN4 temp2
OR IN5 IN6 temp3
OR IN7 IN8 temp4
AND temp1 temp2 temp5
AND temp3 temp4 temp6
XOR temp2 temp6 OUT1
EOF
Var. #0: 'temp1'
Var. #1: 'temp2'
Var. #2: 'temp3'
Var. #3: 'temp4'
Var. #4: 'temp1'
Var. #5: 'temp2'
Var. #6: 'temp5'
Var. #7: 'temp3'
Var. #8: 'temp4'
Var. #9: 'temp6'
Var. #10: 'temp2'
Var. #11: 'temp6'
Report:
nGates: 7, nVars: 12
vars[0]: 'temp1'
vars[1]: 'temp2'
vars[2]: 'temp3'
vars[3]: 'temp4'
vars[4]: 'temp1'
vars[5]: 'temp2'
vars[6]: 'temp5'
vars[7]: 'temp3'
vars[8]: 'temp4'
vars[9]: 'temp6'
vars[10]: 'temp2'
vars[11]: 'temp6'

$

注释:

  1. 我找到了 realloc()在OP的代码中调整变量数组的大小(OP中的tempHeader,我的vars)。我没有找到 - 变量名本身的内存分配。我用过strdup()为此。

  2. 我可以发誓我一直使用 strdup()过去(使用 #include <string.h> 表示正确的原型(prototype))。然而,gcc 提示了,我发现:

    As all functions from Dynamic Memory TR, strdup is only guaranteed to be available if __STDC_ALLOC_LIB__ is defined by the implementation and if the user defines __STDC_WANT_LIB_EXT2__ to the integer constant 1 before including string.h.

    cppreference.com
    我刚刚制作了自己的版本 - 并不太复杂。

  3. strtok() 是这样的功能吗...嗯。它非常古老并且有局限性,这使得它在某些情况下很危险。 (例如,您不应该在线程中使用它。)但是,撇开这些问题不谈,它完美地满足了需要(并且此代码中没有多线程)。

  4. 我使用了固定大小的输入缓冲区 char buffer[80];以保持样本简短。在一个富有成效的项目中,我当然会做一些更复杂的事情,以便能够读取“任意”长度的行——而且我当然需要更多的代码。

  5. 在OP的预期输出中,没有重复的变量。但是,代码示例没有提供任何试图阻止它的代码。因此,我也没有这么做。为此,必须插入以下代码(在唯一出现的 ++nVars; 之前):

    int found = 0;
    for (int i = 0; i < nVars; ++i) {
    if (found = (strcmp(var, vars[i]) == 0)) break;
    }
    if (found) continue; /* continues the while (var = strtok(NULL, " \t\r\n")) loop */
  6. 提供的代码不free()分配的内存。事实上,这不是问题 – 操作系统将在离开后完成这项工作 main() 。然而,“干净”的解决方案是清洁 vars明确地通过:

    /* clean-up */
    for (int i = 0; i < nVars; ++i) free(vars[i]);
    free(vars);

按照建议的更改 5.,输出为:

$ gcc -std=c11 -o testStrtok testStrtok.c

$ ./testStrtok <<'EOF'
OR IN1 IN2 temp1
OR IN3 IN4 temp2
OR IN5 IN6 temp3
OR IN7 IN8 temp4
AND temp1 temp2 temp5
AND temp3 temp4 temp6
XOR temp2 temp6 OUT1
EOF
Var. #0: 'temp1'
Var. #1: 'temp2'
Var. #2: 'temp3'
Var. #3: 'temp4'
Var. #4: 'temp5'
Var. #5: 'temp6'
Report:
nGates: 7, nVars: 6
vars[0]: 'temp1'
vars[1]: 'temp2'
vars[2]: 'temp3'
vars[3]: 'temp4'
vars[4]: 'temp5'
vars[5]: 'temp6'

$

现场演示ideone

关于c - 读取文件,并从临时变量创建字符串数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47803935/

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