我正在尝试编写一个程序,根据给定的用户输入生成一个字符串,然后将该字符串传递给一个函数,该函数将 stdin 更改为虚拟文件,将字符串写入该文件,对所述文件使用 scanf,然后删除文件,但我无法将标准输入重定向到虚拟文件,对只会扩展到函数范围的最佳操作有何帮助?
int scan(const char* __restrict__ _format, ...){
FILE* original = stdin, *mod = calloc(1, sizeof(FILE));
mod = freopen("testFile.txt", "w+", stdin);
fputs(_format, stdin);
int a, b;
scanf("%d %d", &a, &b);
printf("%d, %d", a, b);
// freopen(orig)
return 1;
}
void swap(char* a, char* b) {
if (*a != ' ' && *b != ' ') {
char temp = *a;
*a = *b;
*b = temp;
}
}
void permiate(char* str, int start, int end){
int i;
if(start == end){
printf("%s\n", str);
}else{
for(i = start; i<=end; i++){
swap(str+start, str + i);
permiate(str, start + 1, end);
swap(str + start, str + i);
}
}
}
int main(){
int a, b;
char str[] = "1 3";
//function to put string to stdio
scan(str);
scanf("%d %d", &a, &b);
printf("%d, %d", a, b);
return 0;
}
在有人指出 fscanf(这是一个我从未意识到的函数,因为我的老师从未介绍过它)之后,我找到了扫描函数的有效解决方案:
int scan(const char* __restrict__ _format, ...){
int *a = malloc(sizeof(int)), i = 0;
FILE *fp1 = fopen("testfile.txt", "w");
fputs(_format, fp1);
freopen("testFile.txt", "r", fp1);
while(fscanf(fp1, "%d", &a[i]) != EOF){
i++;
a = realloc(a, sizeof(int)*i);
}
for(int j = 0; j < i; j++){
printf("%d, ", a[j]);
}
fclose(fp1);
return 1;
}
但是每当我给 str 一个像“1 2 3 4 5 6 ...”这样的值或任何超过 5 个数字的值时,如果我保留 realloc,则第 5 个数字始终为 0,如果我注释掉该行,那么就可以了。知道那是什么吗? PS我在大学的实验室只了解了数组的基本用法,没有动态内存或任何东西,所以如果我使用任何错误的东西,我会非常感激
最佳答案
好吧,我想我明白你正在尝试做什么,而且这是可行的,但我当然不会推荐它。每当您freopen()
标准流之一时,都没有可移植的方法来恢复原始标准流。您可以从函数中删除original
,因为它不起作用。也不要分配给 mod
。
话虽如此,您可以将 scan
函数编写为:
int scan(const char* __restrict__ format)
{
int a, b;
FILE *mod = freopen ("dat/freopenab.txt", "w", stdin);
if (!mod) {
perror ("freopen-mod-write");
return 0;
}
fputs (format, stdin); /* write to file as stdin */
stdin = freopen (NULL, "r", mod); /* reopen file "r" as stdin */
if (!stdin) {
perror ("freopen-stdin-read");
return 0;
}
if (scanf("%d %d", &a, &b) != 2) { /* read values from file */
fputs ("error: read of int values failed.\n", stderr);
return 0;
}
printf("%d, %d\n", a, b); /* output resutls */
return 1;
}
stdin
重新打开为上面的文件 "dat/freopenab.txt"
。 format
字符串通过重新打开的 stdin
写入文件。然后再次调用freopen()
,并使用NULL
作为路径名,这允许您更改现有流mod
的模式以读取和分配返回到 stdin
(使 stdin
从文件中读取)
(注意:最好避免使用带前导下划线的变量名)
一个完整的例子是:
#include <stdio.h>
int scan(const char* __restrict__ format)
{
int a, b;
FILE *mod = freopen ("dat/freopenab.txt", "w", stdin);
if (!mod) {
perror ("freopen-mod-write");
return 0;
}
fputs (format, stdin); /* write to file as stdin */
stdin = freopen (NULL, "r", mod); /* reopen file "r" as stdin */
if (!stdin) {
perror ("freopen-stdin-read");
return 0;
}
if (scanf("%d %d", &a, &b) != 2) { /* read values from file */
fputs ("error: read of int values failed.\n", stderr);
return 0;
}
printf("%d, %d\n", a, b); /* output resutls */
return 1;
}
int main (void) {
scan ("12 34\n");
}
示例使用/输出
$ ./bin/freopenab
12, 34
生成的输出/输入文件
$ cat dat/freopenab.txt
12 34
同样,没有可移植的方法将 stdin
恢复到原始状态,尽管在 Linux 上您可以使用 "/dev/tty"
或 “/dev/stdin”
。把事情看一遍,然后尝试一下。然后避免 freopen()
除非没有其他方法可以完成您需要做的事情,而只需再次使用 fopen、fclose 和 fopen
。
关于c - 将字符串传递给 scanf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59349659/