在一行中获取多个输入 C
get multiple inputs in one line C
int main(){
char *inputFile;
char *outputFile;
int numberOfBuffer;
int pageSize;
printf("Enter four inpus, separated by spaces: ");
scanf("%s %s B=%d P=%d", &inputFile,&outputFile,&numberOfBuffer,&pageSize);
readCSV(inputFile,outputFile,numberOfBuffer,pageSize);
return 0;
}
我想通过输入命令行
来读取输入和 运行 readCSV() 方法
students.csv test.csv B=5 P=32
那一行,但我的代码不起作用。有什么帮助吗?
readCSV() 输入类型
readCSV(char* fileName,char* outputFileName, int numberOfBuffer, int pageSize)
您通过将错误类型的数据传递给 scanf()
来调用 未定义的行为 :%s
期望 char*
(指向一个有效的缓冲区足够的长度),但你通过了 char**
.
您应该分配一些数组并将指针传递给它们。表达式中的数组(某些例外情况除外)会自动转换为指向其第一个元素的指针,因此您不需要为它们显式 &
。
您还应该指定要读取的最大长度(最大缓冲区大小减去终止空字符一)以避免缓冲区溢出并检查 scanf()
是否成功读取了所有必需的内容。
int main(){
char inputFile[1024];
char outputFile[1024];
int numberOfBuffer;
int pageSize;
printf("Enter four inpus, separated by spaces: ");
if(scanf("%1023s %1023s B=%d P=%d", inputFile,outputFile,&numberOfBuffer,&pageSize) != 4){
fputs("read error\n", stderr);
return 1;
}
readCSV(inputFile,outputFile,numberOfBuffer,pageSize);
return 0;
}
inputFile
和 outputFile
都需要声明为 数组 of char
大到足以容纳预期的输入1:
#define MAX_FILE_NAME_LENGTH <em>some-value</em>
...
char inputFile[MAX_FILE_NAME_LENGTH+1]; // +1 for string terminator
char outputFile[MAX_FILE_NAME_LENGTH+1];
然后在 scanf
调用中,not 对 inputFile
和 outputFile
使用一元 &
运算符 - 当您将 array 表达式作为参数传递,它会自动转换为指向数组第一个元素的指针。您还想检查 scanf
的结果以确保您获得了所有输入:
if ( scanf( "%s %s B=%d P=%d", inputFile, outputFile, &numberOfBuffer, &pageSize ) != 4 )
{
// bad input somewhere, probably with numberOfBuffer or pageSize,
// handle as appropriate
}
else
{
// process input normally
}
但是...
scanf
是一个糟糕 的交互式输入工具。很难做到防弹,对于像这样的东西,你最好使用 fgets
或类似的东西将整个东西作为一个大字符串读取,然后从该字符串中提取数据。
可能有助于为您简化这一过程的一件事是,您不必在单个 scanf
调用中阅读整行。您可以单独阅读每个元素:
/**
* Start by reading the input file name; we use `fgets` instead
* of `scanf` because it's easier to protect against a buffer overflow
*/
if ( !fgets( inputFile, sizeof inputFile, stdin ) )
{
// error reading input file name, handle as appropriate
}
/**
* Successfully read inputFile, now read outputFile
*/
else if ( !fgets( outputFile, sizeof outputFile, stdin ) )
{
// error reading output file name, handle as appropriate
}
/**
* Now get the number of buffers - the leading blank in the format
* string tells scanf to skip over any leading whitespace, otherwise
* if you have more than one blank between the end of the output file
* name and the 'B' the read will fail.
*/
else if ( scanf( " B=%d", &numberOfBuffer ) != 1 )
{
// error getting number of buffers, handle as appropriate
}
/**
* And finally the page size, with the same leading blank space in the
* format string.
*/
else if ( scanf( " P=%d", &pageSize ) != 1 )
{
// error getting page size, handle as appropriate
}
else
{
// process all inputs normally.
}
- 或者它们的内存需要动态分配,但由于您刚刚学习 C,因此需要稍后解决。
您的大部分问题都是由于误用scanf造成的。这里的解决方案不是修复您对 scanf 的使用,而是完全避免它。 (http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html) 这样的参数应该来自命令行参数,而不是来自输入流。保持输入流清晰几乎总是更好,这样它就可以用于收集数据。 (例如,将您的程序编写为过滤器。)例如:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static void
check_prefix(const char *a, const char *prefix)
{
if( strncmp(a, prefix, strlen(prefix)) ){
fprintf(stderr, "Invalid argument: %s Must start with, %s\n",
a, prefix);
exit(EXIT_FAILURE);
}
}
static void
readCSV(const char *in, const char *out, int n, int p)
{
printf("in = %s, out = %s, n = %d, p = %d\n", in, out, n, p);
}
int
main(int argc, char **argv)
{
if( argc < 5 ){
fprintf(stderr, "Invalid number of arguments\n");
return EXIT_FAILURE;
}
check_prefix(argv[3], "B=");
check_prefix(argv[4], "P=");
char *inputFile = argv[1];
char *outputFile = argv[2];
int numberOfBuffer = strtol(argv[3] + 2, NULL, 10);
int pageSize = strtol(argv[4] + 2, NULL, 10);
readCSV(inputFile, outputFile, numberOfBuffer, pageSize);
return 0;
}
int main(){
char *inputFile;
char *outputFile;
int numberOfBuffer;
int pageSize;
printf("Enter four inpus, separated by spaces: ");
scanf("%s %s B=%d P=%d", &inputFile,&outputFile,&numberOfBuffer,&pageSize);
readCSV(inputFile,outputFile,numberOfBuffer,pageSize);
return 0;
}
我想通过输入命令行
来读取输入和 运行 readCSV() 方法students.csv test.csv B=5 P=32
那一行,但我的代码不起作用。有什么帮助吗? readCSV() 输入类型
readCSV(char* fileName,char* outputFileName, int numberOfBuffer, int pageSize)
您通过将错误类型的数据传递给 scanf()
来调用 未定义的行为 :%s
期望 char*
(指向一个有效的缓冲区足够的长度),但你通过了 char**
.
您应该分配一些数组并将指针传递给它们。表达式中的数组(某些例外情况除外)会自动转换为指向其第一个元素的指针,因此您不需要为它们显式 &
。
您还应该指定要读取的最大长度(最大缓冲区大小减去终止空字符一)以避免缓冲区溢出并检查 scanf()
是否成功读取了所有必需的内容。
int main(){
char inputFile[1024];
char outputFile[1024];
int numberOfBuffer;
int pageSize;
printf("Enter four inpus, separated by spaces: ");
if(scanf("%1023s %1023s B=%d P=%d", inputFile,outputFile,&numberOfBuffer,&pageSize) != 4){
fputs("read error\n", stderr);
return 1;
}
readCSV(inputFile,outputFile,numberOfBuffer,pageSize);
return 0;
}
inputFile
和 outputFile
都需要声明为 数组 of char
大到足以容纳预期的输入1:
#define MAX_FILE_NAME_LENGTH <em>some-value</em>
...
char inputFile[MAX_FILE_NAME_LENGTH+1]; // +1 for string terminator
char outputFile[MAX_FILE_NAME_LENGTH+1];
然后在 scanf
调用中,not 对 inputFile
和 outputFile
使用一元 &
运算符 - 当您将 array 表达式作为参数传递,它会自动转换为指向数组第一个元素的指针。您还想检查 scanf
的结果以确保您获得了所有输入:
if ( scanf( "%s %s B=%d P=%d", inputFile, outputFile, &numberOfBuffer, &pageSize ) != 4 )
{
// bad input somewhere, probably with numberOfBuffer or pageSize,
// handle as appropriate
}
else
{
// process input normally
}
但是...
scanf
是一个糟糕 的交互式输入工具。很难做到防弹,对于像这样的东西,你最好使用 fgets
或类似的东西将整个东西作为一个大字符串读取,然后从该字符串中提取数据。
可能有助于为您简化这一过程的一件事是,您不必在单个 scanf
调用中阅读整行。您可以单独阅读每个元素:
/**
* Start by reading the input file name; we use `fgets` instead
* of `scanf` because it's easier to protect against a buffer overflow
*/
if ( !fgets( inputFile, sizeof inputFile, stdin ) )
{
// error reading input file name, handle as appropriate
}
/**
* Successfully read inputFile, now read outputFile
*/
else if ( !fgets( outputFile, sizeof outputFile, stdin ) )
{
// error reading output file name, handle as appropriate
}
/**
* Now get the number of buffers - the leading blank in the format
* string tells scanf to skip over any leading whitespace, otherwise
* if you have more than one blank between the end of the output file
* name and the 'B' the read will fail.
*/
else if ( scanf( " B=%d", &numberOfBuffer ) != 1 )
{
// error getting number of buffers, handle as appropriate
}
/**
* And finally the page size, with the same leading blank space in the
* format string.
*/
else if ( scanf( " P=%d", &pageSize ) != 1 )
{
// error getting page size, handle as appropriate
}
else
{
// process all inputs normally.
}
- 或者它们的内存需要动态分配,但由于您刚刚学习 C,因此需要稍后解决。
您的大部分问题都是由于误用scanf造成的。这里的解决方案不是修复您对 scanf 的使用,而是完全避免它。 (http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html) 这样的参数应该来自命令行参数,而不是来自输入流。保持输入流清晰几乎总是更好,这样它就可以用于收集数据。 (例如,将您的程序编写为过滤器。)例如:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static void
check_prefix(const char *a, const char *prefix)
{
if( strncmp(a, prefix, strlen(prefix)) ){
fprintf(stderr, "Invalid argument: %s Must start with, %s\n",
a, prefix);
exit(EXIT_FAILURE);
}
}
static void
readCSV(const char *in, const char *out, int n, int p)
{
printf("in = %s, out = %s, n = %d, p = %d\n", in, out, n, p);
}
int
main(int argc, char **argv)
{
if( argc < 5 ){
fprintf(stderr, "Invalid number of arguments\n");
return EXIT_FAILURE;
}
check_prefix(argv[3], "B=");
check_prefix(argv[4], "P=");
char *inputFile = argv[1];
char *outputFile = argv[2];
int numberOfBuffer = strtol(argv[3] + 2, NULL, 10);
int pageSize = strtol(argv[4] + 2, NULL, 10);
readCSV(inputFile, outputFile, numberOfBuffer, pageSize);
return 0;
}