Да, в вашем formula
вы можете cbind
числовые переменные быть агрегированными:
aggregate(cbind(x1, x2) ~ year + month, data = df1, sum, na.rm = TRUE)
year month x1 x2
1 2000 1 7.862002 -7.469298
2 2001 1 276.758209 474.384252
3 2000 2 13.122369 -128.122613
...
23 2000 12 63.436507 449.794454
24 2001 12 999.472226 922.726589
См. ?aggregate
, аргумент formula
и примеры.
Введите во время сохранения области динамически
E.G.
#include <stdio.h>
#include <stdlib.h>
char *inputString(FILE* fp, size_t size){
//The size is extended by the input with the value of the provisional
char *str;
int ch;
size_t len = 0;
str = realloc(NULL, sizeof(char)*size);//size is start size
if(!str)return str;
while(EOF!=(ch=fgetc(fp)) && ch != '\n'){
str[len++]=ch;
if(len==size){
str = realloc(str, sizeof(char)*(size+=16));
if(!str)return str;
}
}
str[len++]='\0';
return realloc(str, sizeof(char)*len);
}
int main(void){
char *m;
printf("input string : ");
m = inputString(stdin, 10);
printf("%s\n", m);
free(m);
return 0;
}
Я видел только один простой способ чтения произвольно длинной строки, но я никогда не использовал его. Я думаю, что это выглядит так:
char *m = NULL;
printf("please input a string\n");
scanf("%ms",&m);
if (m == NULL)
fprintf(stderr, "That string was too long!\n");
else
{
printf("this is the string %s\n",m);
/* ... any other use of m */
free(m);
}
m
между %
и s
сообщает scanf()
, чтобы измерить строку и выделить для нее память, и скопировать строку в нее, и для сохранения адреса этой выделенной памяти в соответствующем аргументе. После того, как вы закончите с этим, вы должны free()
его.
. Однако это не поддерживается для каждой реализации scanf()
.
Как указывали другие, самым простым решением является ограничение на длину ввода. Если вы все еще хотите использовать scanf()
, вы можете сделать это следующим образом:
char m[100];
scanf("%99s",&m);
Обратите внимание, что размер m[]
должен быть как минимум на один байт больше, чем число между %
и s
.
Если введенная строка длиннее 99, остальные символы будут ждать, чтобы их прочитал другой вызов или остальная часть строки формата, переданной в scanf()
.
Как правило scanf()
не рекомендуется для обработки пользовательского ввода. Он лучше всего применяется к базовым структурированным текстовым файлам, которые были созданы другим приложением. Даже тогда вы должны знать, что вход не может быть отформатирован так, как вы ожидаете, поскольку кто-то мог помешать ему попытаться сломать вашу программу.
Прочитайте прямо в выделенное пространство с помощью fgets()
.
Особое внимание следует уделить распознаванию успешной ошибки чтения, конца файла, ввода и выхода из памяти.
Этот метод сохраняет строку '\n'
.
#include <stdio.h>
#include <stdlib.h>
#define FGETS_ALLOC_N 128
char* fgets_alloc(FILE *istream) {
char* buf = NULL;
size_t size = 0;
size_t used = 0;
do {
size += FGETS_ALLOC_N;
char *buf_new = realloc(buf, size);
if (buf_new == NULL) {
// Out-of-memory
free(buf);
return NULL;
}
buf = buf_new;
if (fgets(&buf[used], (int) (size - used), istream) == NULL) {
// feof or ferror
if (used == 0 || ferror(istream)) {
free(buf);
buf = NULL;
}
return buf;
}
size_t length = strlen(&buf[used]);
if (length + 1 != size - used) break;
used += length;
} while (buf[used - 1] != '\n');
return buf;
}
Использование образца
int main(void) {
FILE *istream = stdin;
char *s;
while ((s = fgets_alloc(istream)) != NULL) {
printf("'%s'", s);
free(s);
fflush(stdout);
}
if (ferror(istream)) {
puts("Input error");
} else if (feof(istream)) {
puts("End of file");
} else {
puts("Out of memory");
}
return 0;
}
Возьмите указатель на символ для хранения требуемой строки. Если у вас есть представление о возможном размере строки, используйте функцию
char *fgets (char *str, int size, FILE* file);`
, иначе вы также можете выделить память во время выполнения, используя malloc () , которая динамически обеспечивает запрошенную память.
Более безопасная и быстрая (удвоенная емкость) версия:
char *readline(char *prompt) {
size_t size = 80;
char *str = malloc(sizeof(char) * size);
int c;
size_t len = 0;
printf("%s", prompt);
while (EOF != (c = getchar()) && c != '\r' && c != '\n') {
str[len++] = c;
if(len == size) str = realloc(str, sizeof(char) * (size *= 2));
}
str[len++]='\0';
return realloc(str, sizeof(char) * len);
}
С компьютерами сегодняшнего дня вы можете избавиться от выделения очень больших строк (сотни тысяч символов), в то время как вряд ли сделайте вмятину в использовании ОЗУ компьютера. Поэтому я не стал бы слишком беспокоиться.
Однако, в прежние времена, когда память была на высоте, обычной практикой было чтение строк в кусках. fgets
считывает до максимального количества символов из ввода, но оставляет остальную часть входного буфера неповрежденной, поэтому вы можете прочитать остальное от него, как вам нравится.
в этом примере, я читал в кусках 200 символов, но вы можете использовать любой размер блока, который вы хотите, конечно.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* readinput()
{
#define CHUNK 200
char* input = NULL;
char tempbuf[CHUNK];
size_t inputlen = 0, templen = 0;
do {
fgets(tempbuf, CHUNK, stdin);
templen = strlen(tempbuf);
inputlen += templen;
input = realloc(input, inputlen+1);
strcat(input, tempbuf);
} while (templen==CHUNK-1 && tempbuf[CHUNK-2]!='\n');
return input;
}
int main()
{
char* result = readinput();
printf("And the result is [%s]\n", result);
free(result);
return 0;
}
Обратите внимание, что это упрощенный пример без проверки ошибок; в реальной жизни вам нужно будет убедиться, что ввод в порядке, подтвердив возвращаемое значение fgets
.
Также обратите внимание, что в конце, если процедура readinput, никакие байты не теряются; строка имеет точный размер памяти, который должен иметь.
Если я могу предложить более безопасный подход:
Объявить буфер, достаточно большой для хранения строки:
char user_input[255];
Получить вход пользователя в безопасный способ:
fgets(user_input, 255, stdin);
Безопасный способ получения ввода, первый аргумент - указатель на буфер, в котором будет сохранен вход, второй - максимальный вход функция должна читать, а третья - указатель на стандартный вход, т. е. откуда поступает пользовательский вход.
Безопасность, в частности, вытекает из второго аргумента, ограничивающего количество чтений, которое предотвращает переполнение буфера. Кроме того, fgets
заботится о нулевом завершении обрабатываемой строки.
Подробнее о этой функции здесь .
EDIT: Если вам нужно сделать любое форматирование (например, преобразование строки в число), вы можете использовать atoi после ввода.
У меня также есть решение со стандартными входами и выходами
#include<stdio.h>
#include<malloc.h>
int main()
{
char *str,ch;
int size=10,len=0;
str=realloc(NULL,sizeof(char)*size);
if(!str)return str;
while(EOF!=scanf("%c",&ch) && ch!="\n")
{
str[len++]=ch;
if(len==size)
{
str = realloc(str,sizeof(char)*(size+=10));
if(!str)return str;
}
}
str[len++]='\0';
printf("%s\n",str);
free(str);
}
Я знаю, что я приехал через 4 года и уже слишком поздно, но я думаю, что у меня есть другой способ, которым может воспользоваться кто-то. Я использовал функцию getchar()
следующим образом: -
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//I had putten the main Function Bellow this function.
//d for asking string,f is pointer to the string pointer
void GetStr(char *d,char **f)
{
printf("%s",d);
for(int i =0;1;i++)
{
if(i)//I.e if i!=0
*f = (char*)realloc((*f),i+1);
else
*f = (char*)malloc(i+1);
(*f)[i]=getchar();
if((*f)[i] == '\n')
{
(*f)[i]= '\0';
break;
}
}
}
int main()
{
char *s =NULL;
GetStr("Enter the String:- ",&s);
printf("Your String:- %s \nAnd It's length:- %lu\n",s,(strlen(s)));
free(s);
}
вот образец для этой программы: -
Enter the String:- I am Using Linux Mint XFCE 18.2 , eclispe CDT and GCC7.2 compiler!!
Your String:- I am Using Linux Mint XFCE 18.2 , eclispe CDT and GCC7.2 compiler!!
And It's length:- 67