将来自标准输入的输入存储到列表中
storing input from stdin into list
我将获得以下格式的输入,我希望将其存储到数组列表或链表中(以更容易实现的为准):
3,5;6,7;8,9;11,4;
我希望能够将 ;
之前的两个数字放入一个结构中并存储它们。比如我想把3,5组合在一起,把6,7组合在一起。
我不确定如何读取输入并获取每一对并存储它。我将要获得的输入可能相当大(高达 60-70mB)。
我曾尝试使用 strtok()
和 strtol()
,但我似乎无法获得正确的实现。
任何帮助都会很棒
编辑:
到目前为止,我一直在尝试使用这段代码来读取输入:
char[1000] remainder;
int first, second;
fp = fopen("C:\file.txt", "r"); // Error check this, probably.
while (fgets(&remainder, 1000, fp) != null) { // Get a line.
while (sscanf(remainder, "%d,%d;%s", first, second, remainder) != null) {
// place first and second into a struct or something
}
}
我修复了代码中的语法错误,但是当我尝试编译时,它崩溃了。
只需添加一行,相同的答案就可以为您的问题提供可靠且灵活的解决方案。花点时间了解它的作用。它一点也不复杂,它只是基本的 C。为了让您从 string
转换为 int
,您有 libc[=26= 提供的 2 个选择]、atoi
(无错误检查)和strtol
(有错误检查)。您唯一的另一种选择是手动编写转换代码,鉴于您在此问题的两个版本中的评论,这不是您想要的。
下面是一个很好的解决方案。花时间了解它的作用。不管你用fgets
还是getline
,解决问题的方法都是一样的。让我知道你的问题是什么:
/* read unliminted number of int values into array from stdin
(semicolon or comma separated values, pair every 2 values)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define NMAX 256
int main () {
char *ln = NULL; /* NULL forces getline to allocate */
size_t n = 0; /* max chars to read (0 - no limit) */
ssize_t nchr = 0; /* number of chars actually read */
int *numbers = NULL; /* array to hold numbers */
size_t nmax = NMAX; /* check for reallocation */
size_t idx = 0; /* numbers array index */
if (!(numbers = calloc (NMAX, sizeof *numbers))) {
fprintf (stderr, "error: memory allocation failed.");
return 1;
}
/* read each line from stdin - dynamicallly allocated */
while ((nchr = getline (&ln, &n, stdin)) != -1)
{
char *p = ln; /* pointer for use with strtol */
char *ep = NULL;
errno = 0;
while (errno == 0)
{
/* parse/convert each number on stdin */
numbers[idx] = strtol (p, &ep, 10);
/* note: overflow/underflow checks omitted */
/* if valid conversion to number */
if (errno == 0 && p != ep)
{
idx++; /* increment index */
if (!ep) break; /* check for end of str */
}
/* skip delimiters/move pointer to next digit */
while (*ep && (*ep <= '0' || *ep >= '9')) ep++;
if (*ep)
p = ep;
else
break;
/* reallocate numbers if idx = nmax */
if (idx == nmax)
{
int *tmp = realloc (numbers, 2 * nmax * sizeof *numbers);
if (!tmp) {
fprintf (stderr, "Error: struct reallocation failure.\n");
exit (EXIT_FAILURE);
}
numbers = tmp;
memset (numbers + nmax, 0, nmax * sizeof *numbers);
nmax *= 2;
}
}
}
/* free mem allocated by getline */
if (ln) free (ln);
/* show values stored in array */
size_t i = 0;
for (i = 0; i < idx; i++)
if ( i % 2 == 1 ) /* pair ever 2 values */
printf (" numbers[%2zu] numbers[%2zu] %d, %d\n", i-1, i, numbers[i-1], numbers[i]);
/* free mem allocated to numbers */
if (numbers) free (numbers);
return 0;
}
输出
$ echo "3,5;6,7;8,9;11,4;;" | ./bin/parsestdin2
numbers[ 0] numbers[ 1] 3, 5
numbers[ 2] numbers[ 3] 6, 7
numbers[ 4] numbers[ 5] 8, 11
我将获得以下格式的输入,我希望将其存储到数组列表或链表中(以更容易实现的为准):
3,5;6,7;8,9;11,4;
我希望能够将 ;
之前的两个数字放入一个结构中并存储它们。比如我想把3,5组合在一起,把6,7组合在一起。
我不确定如何读取输入并获取每一对并存储它。我将要获得的输入可能相当大(高达 60-70mB)。
我曾尝试使用 strtok()
和 strtol()
,但我似乎无法获得正确的实现。
任何帮助都会很棒
编辑:
到目前为止,我一直在尝试使用这段代码来读取输入:
char[1000] remainder;
int first, second;
fp = fopen("C:\file.txt", "r"); // Error check this, probably.
while (fgets(&remainder, 1000, fp) != null) { // Get a line.
while (sscanf(remainder, "%d,%d;%s", first, second, remainder) != null) {
// place first and second into a struct or something
}
}
我修复了代码中的语法错误,但是当我尝试编译时,它崩溃了。
只需添加一行,相同的答案就可以为您的问题提供可靠且灵活的解决方案。花点时间了解它的作用。它一点也不复杂,它只是基本的 C。为了让您从 string
转换为 int
,您有 libc[=26= 提供的 2 个选择]、atoi
(无错误检查)和strtol
(有错误检查)。您唯一的另一种选择是手动编写转换代码,鉴于您在此问题的两个版本中的评论,这不是您想要的。
下面是一个很好的解决方案。花时间了解它的作用。不管你用fgets
还是getline
,解决问题的方法都是一样的。让我知道你的问题是什么:
/* read unliminted number of int values into array from stdin
(semicolon or comma separated values, pair every 2 values)
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define NMAX 256
int main () {
char *ln = NULL; /* NULL forces getline to allocate */
size_t n = 0; /* max chars to read (0 - no limit) */
ssize_t nchr = 0; /* number of chars actually read */
int *numbers = NULL; /* array to hold numbers */
size_t nmax = NMAX; /* check for reallocation */
size_t idx = 0; /* numbers array index */
if (!(numbers = calloc (NMAX, sizeof *numbers))) {
fprintf (stderr, "error: memory allocation failed.");
return 1;
}
/* read each line from stdin - dynamicallly allocated */
while ((nchr = getline (&ln, &n, stdin)) != -1)
{
char *p = ln; /* pointer for use with strtol */
char *ep = NULL;
errno = 0;
while (errno == 0)
{
/* parse/convert each number on stdin */
numbers[idx] = strtol (p, &ep, 10);
/* note: overflow/underflow checks omitted */
/* if valid conversion to number */
if (errno == 0 && p != ep)
{
idx++; /* increment index */
if (!ep) break; /* check for end of str */
}
/* skip delimiters/move pointer to next digit */
while (*ep && (*ep <= '0' || *ep >= '9')) ep++;
if (*ep)
p = ep;
else
break;
/* reallocate numbers if idx = nmax */
if (idx == nmax)
{
int *tmp = realloc (numbers, 2 * nmax * sizeof *numbers);
if (!tmp) {
fprintf (stderr, "Error: struct reallocation failure.\n");
exit (EXIT_FAILURE);
}
numbers = tmp;
memset (numbers + nmax, 0, nmax * sizeof *numbers);
nmax *= 2;
}
}
}
/* free mem allocated by getline */
if (ln) free (ln);
/* show values stored in array */
size_t i = 0;
for (i = 0; i < idx; i++)
if ( i % 2 == 1 ) /* pair ever 2 values */
printf (" numbers[%2zu] numbers[%2zu] %d, %d\n", i-1, i, numbers[i-1], numbers[i]);
/* free mem allocated to numbers */
if (numbers) free (numbers);
return 0;
}
输出
$ echo "3,5;6,7;8,9;11,4;;" | ./bin/parsestdin2
numbers[ 0] numbers[ 1] 3, 5
numbers[ 2] numbers[ 3] 6, 7
numbers[ 4] numbers[ 5] 8, 11