C loop to read lines of input - c

I want to create a program in C that takes an arbitrary number of lines of arbitrary length as input and then prints to console the last line that was inputted. For example:
input:
hi
my name is
david
output: david
I figured the best way to do this would be to have a loop that takes each line as input and stores it in a char array, so at the end of the loop the last line ends up being what is stored in the char array and we can just print that.
I have only had one lecture in C so far so I think I just keep setting things up wrong with my Java/C++ mindset since I have more experience in those languages.
Here is what I have so far but I know that it's nowhere near correct:
#include <stdio.h>
int main()
{
printf("Enter some lines of strings: \n");
char line[50];
for(int i = 0; i < 10; i++){
line = getline(); //I know this is inproper syntax but I want to do something like this
}
printf("%s",line);
}
I also have i < 10 in the loop because I don't know how to find the total number of lines in the input which, would be the proper amount of times to loop this. Also, the input is being put in all at once from the
./program < test.txt
command in Unix shell, where test.txt has the input.

Use fgets():
while (fgets(line, sizeof line, stdin)) {
// don't need to do anything here
}
printf("%s", line);
You don't need a limit on the number of iterations. At the end of the file, fgets() returns NULL and doesn't modify the buffer, so line will still hold the last line that was read.

I'm assuming you know the maximum length of the input line.
This one here will surely do the job for you
static char *getLine( char * const b , size_t bsz ) {
return fgets(b, bsz, stdin) );
}
But remember fgets also puts a '\n' character at the end of buffer so perhaps something like this
static char *getLine( char * const b , size_t bsz ) {
if( fgets(b, bsz, stdin) ){
/* Optional code to strip NextLine */
size_t size = strlen(b);
if( size > 0 && b[size-1] == '\n' ) {
b[--size] = '\0';
}
/* End of Optional Code */
return b;
}
return NULL;
}
and your code needs to be altered a bit while calling the getline
#define BUF_SIZE 256
char line[BUF_SIZE];
for(int i = 0; i < 10; i++){
if( getLine(line, BUF_SIZE ) ) {
fprintf(stdout, "line : '%s'\n", line);
}
}
Now it is how ever quite possible to create function like
char *getLine();
but then one needs to define the behavior of that function for instance if the function getLine() allocates memory dynamically then you probably need use a free to de-allocate the pointer returned by getLine()
in which case the function may look like
char *getLine( size_t bsz ) {
char *b = malloc( bsz );
if( b && fgets(b, bsz, stdin) ){
return b;
}
return NULL;
}
depending on how small your function is you can entertain thoughts about making it inline perhaps that's a little off topic for now.

In order to have dynamic number of input of dynamic length, you have to keep on reallocating your buffer when the input is of greater length. In order to store the last line, you have to take another pointer to keep track of it and to stop the input from the terminal you have to press EOF key(ctrl+k). This should do your job.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *get_last_line(FILE* fp, size_t size){
//The size is extended by the input with the value of the provisional
char *str, *last_str = NULL;
int ch;
size_t len = 0, last_len = 0;
str = realloc(NULL, sizeof(char)*size);//size is start size
if(!str)return str;
while(ch=fgetc(fp)){
if(ch == EOF){
break;
}
if(ch == '\n'){
str[len]='\0';
last_len = len;
last_str = realloc(last_str,sizeof(char)*last_len);
last_str[last_len]='\0';
//storing the last line
memcpy(last_str,str,sizeof(char)*last_len);
str = realloc(NULL, sizeof(char)*size);//size is start size
len = 0;
}
else {
str[len++]=ch;
if(len==size){
str = realloc(str, sizeof(char)*(size+=16));
if(!str)return str;
}
}
}
free(str);
return last_str;
}
int main(void){
char *m;
printf("input strings : ");
m = get_last_line(stdin, 10);
printf("last string :");
printf("%s\n", m);
free(m);
return 0;
}

Related

Dynamically create array in C taking in 1 character at a time

I am given an assignment to take in and store a string using a function, however, I am given some restrictions.
Only able to use getchar() to take in user input character by character
No assumption of length of the input (Not allowed to create a array of size 100 for example)
Not allowed to read the input twice, for example, using the first round of input to count string size and then ask the user to input again after creating an array of the string's size that was counted on the first round.
Not allowed to create a large buffer so a constant size buffer means memory will be wasted if the input is 1 character for example
int read_string()
{
char* input;
int counter = 0;
while (( input = getchar()) != '\n') //read until detect '\n'
{
printf("%c\n",input);
counter = counter + 1;
}
printf("Length of string: %d\n", counter);
}
I currently have no idea how to store character by character and dynamically resize an "array" like vectors equivalent in C++. C does not have vectors based on my research.
Based on my code now, when i type in "Hello",
the output will be
h
e
l
l
o
but I do not know how to store each character in a dynamic array
You'd have to use the realloc function, if you want to dynamically increase the size with every new character that you read.
When you use realloc, the content of the memory block is preserved up to the lesser of the new and old sizes, even if the block is moved to a new location. If the function fails to allocate the requested block of memory, a null pointer is returned.
For every character that I read, I increment buffsize, but I do allocate buffsize + 1. Why? Because I need one extra position for the NULL terminator.
The last free position for a letter would be buffsize - 1 in this case and the last one will be assigned at the end of the while loop.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
size_t buffsize = 0;
char *buffer = NULL;
char *temp;
char input;
while ((input = getchar()) != '\n') {
printf("%c\n", input);
/* Incraese the size & realloc */
++buffsize;
temp = realloc(buffer, (buffsize + 1) * sizeof(char));
if (!temp) {
printf("Error reallocating buffer!\n");
exit(1);
}
/* Setting the new read char */
buffer = temp;
buffer[buffsize - 1] = input;
}
if (buffsize) {
buffer[buffsize] = '\0';
printf("Result = [%s]\n", buffer);
} else {
printf("Empty input!\n");
}
printf("String size=%lu\n", buffsize);
/* Clean */
free(buffer);
return 0;
}
A bit more generic - function which adds a char to the string. Initially pointer should be NULL and it will take it into account automatically
char *addchar(char **str, int c)
{
size_t len= 0;
char *tmp;
if(*str)
{
len = strlen(*str);
}
tmp = realloc(*str, len + 2);
if(tmp)
{
*str = tmp;
tmp[len] = c;
tmp[len + 1] = 0;
}
return tmp;
}
and usage - a bit different than yours
int main()
{
char *mystring = NULL;
int input;
while (( input = getchar()) != EOF)
{
if(input == '\n' || input == '\r') continue;
if(!addchar(&mystring, input))
{
printf("\nMemory allocation error\n");
}
else
{
printf("String length %zu\n", strlen(mystring));
}
}
}
First off, the function getchar() returns and int not char * so you should not assign its return value to the pointer input declared in your code as char* input;
You should start by declaring an int variable; could be called len ; and initialize it with the value of 0. Next you should call the function malloc() and feed it 1 to allocate 1 byte of memory to hold a single character, and assign its return value to the pointer input, like the following:
int len = 0;
input = malloc(1);
Then you should store the NUL-terminating character '\0' in the allocated memory:
input[0] = '\0';
Then you create an int variable since the return value of getchar() is int. This variable which could be called ch shall store the user input.
Then you increase the size of your allocated storage to accommodate the new character:
input = realloc(input, len + 1);
input[len] = ch;
len++;
The entire code should look like the following:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int len = 0;
char *input = malloc(1);
input[0] = '\0';
int ch;
while ((ch = getchar()) != '\n')
{
input = realloc(input, len + 1);
input[len] = ch;
len++;
}
input[len] = '\0';
printf("You entered: %s\n", input);
printf("Length of str: %d\n", len);
free(input);
return 0;
}

Input a char string with any size [duplicate]

If I don't know how long the word is, I cannot write char m[6];,
The length of the word is maybe ten or twenty long.
How can I use scanf to get input from the keyboard?
#include <stdio.h>
int main(void)
{
char m[6];
printf("please input a string with length=5\n");
scanf("%s",&m);
printf("this is the string: %s\n", m);
return 0;
}
please input a string with length=5
input: hello
this is the string: hello
Enter while securing an area dynamically
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(*str)*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(*str)*(size+=16));
if(!str)return str;
}
}
str[len++]='\0';
return realloc(str, sizeof(*str)*len);
}
int main(void){
char *m;
printf("input string : ");
m = inputString(stdin, 10);
printf("%s\n", m);
free(m);
return 0;
}
With the computers of today, you can get away with allocating very large strings (hundreds of thousands of characters) while hardly making a dent in the computer's RAM usage. So I wouldn't worry too much.
However, in the old days, when memory was at a premium, the common practice was to read strings in chunks. fgets reads up to a maximum number of chars from the input, but leaves the rest of the input buffer intact, so you can read the rest from it however you like.
in this example, I read in chunks of 200 chars, but you can use whatever chunk size you want of course.
#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);
input = realloc(input, inputlen+templen+1);
strcpy(input+inputlen, tempbuf);
inputlen += templen;
} 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;
}
Note that this is a simplified example with no error checking; in real life you will have to make sure the input is OK by verifying the return value of fgets.
Also note that at the end if the readinput routine, no bytes are wasted; the string has the exact memory size it needs to have.
I've seen only one simple way of reading an arbitrarily long string, but I've never used it. I think it goes like this:
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);
}
The m between % and s tells scanf() to measure the string and allocate memory for it and copy the string into that, and to store the address of that allocated memory in the corresponding argument. Once you're done with it you have to free() it.
This isn't supported on every implementation of scanf(), though.
As others have pointed out, the easiest solution is to set a limit on the length of the input. If you still want to use scanf() then you can do so this way:
char m[100];
scanf("%99s",&m);
Note that the size of m[] must be at least one byte larger than the number between % and s.
If the string entered is longer than 99, then the remaining characters will wait to be read by another call or by the rest of the format string passed to scanf().
Generally scanf() is not recommended for handling user input. It's best applied to basic structured text files that were created by another application. Even then, you must be aware that the input might not be formatted as you expect, as somebody might have interfered with it to try to break your program.
There is a new function in C standard for getting a line without specifying its size. getline function allocates string with required size automatically so there is no need to guess about string's size. The following code demonstrate usage:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *line = NULL;
size_t len = 0;
ssize_t read;
while ((read = getline(&line, &len, stdin)) != -1) {
printf("Retrieved line of length %zu :\n", read);
printf("%s", line);
}
if (ferror(stdin)) {
/* handle error */
}
free(line);
return 0;
}
If I may suggest a safer approach:
Declare a buffer big enough to hold the string:
char user_input[255];
Get the user input in a safe way:
fgets(user_input, 255, stdin);
A safe way to get the input, the first argument being a pointer to a buffer where the input will be stored, the second the maximum input the function should read and the third is a pointer to the standard input - i.e. where the user input comes from.
Safety in particular comes from the second argument limiting how much will be read which prevents buffer overruns. Also, fgets takes care of null-terminating the processed string.
More info on that function here.
EDIT: If you need to do any formatting (e.g. convert a string to a number), you can use atoi once you have the input.
Safer and faster (doubling capacity) version:
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);
}
Read directly into allocated space with fgets().
Special care is need to distinguish a successful read, end-of-file, input error and out-of memory. Proper memory management needed on EOF.
This method retains a line's '\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;
}
Sample usage
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;
}
I know that I have arrived after 4 years and am too late but I think I have another way that someone can use. I had used getchar() Function like this:-
#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);
}
here is the sample run for this program:-
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
Take a character pointer to store required string.If you have some idea about possible size of string then use function
char *fgets (char *str, int size, FILE* file);
else you can allocate memory on runtime too using malloc() function which dynamically provides requested memory.
i also have a solution with standard inputs and outputs
#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);
}
I have a solution using standard libraries of C and also creating a string type (alias of char*) like in C++
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char* string;
typedef struct __strstr {
char ch;
struct __strstr *next;
}Strstr;
void get_str(char **str) {
char ch, *buffer, a;
Strstr *new = NULL;
Strstr *head = NULL, *tmp = NULL;
int c = 0, k = 0;
while ((ch = getchar()) != '\n') {
new = malloc(sizeof(Strstr));
if(new == NULL) {
printf("\nError!\n");
exit(1);
}
new->ch = ch;
new->next = NULL;
new->next = head;
head = new;
}
tmp = head;
while (tmp != NULL) {
c++;
tmp = tmp->next;
}
if(c == 0) {
*str = "";
} else {
buffer = malloc(sizeof(char) * (c + 1));
*str = malloc(sizeof(char) * (c + 1));
if(buffer == NULL || *str == NULL) {
printf("\nError!\n");
exit(1);
}
tmp = head;
while (tmp != NULL) {
buffer[k] = tmp->ch;
k++;
tmp = tmp->next;
}
buffer[k] = '\0';
for (int i = 0, j = strlen(buffer)-1; i < j; i++, j--) {
a = buffer[i];
buffer[i] = buffer[j];
buffer[j] = a;
}
strcpy(*str, buffer);
// Dealloc
free(buffer);
while (head != NULL) {
tmp = head;
head = head->next;
free(tmp);
}
}
}
int main() {
string str;
printf("Enter text: ");
get_str(&str);
printf("%s\n", str);
return 0;
}

How do I convert a string to a numeric value in C?

It would be better If I show you guys an example of what my program is supposed to do.
Input:
3
Double Double End
Triple Double End
Quadruple Double Triple End
Output:
4
6
24
So, the first sentence Double Double means 2*2 and Triple Double means 3*2 and so on.
The word End signifies the end of the string.
It looks very simple, but I have no idea how to work with strings and give them a value and continue on from there.
Here is all I have done so far:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num_of_orders,i,j;
char orders[25];
char str1[25] = "Double";
char str2[25] = "Triple";
char str3[25] = "Quadruple";
scanf("%d", &num_of_orders);
for (i=0; i<num_of_orders+1; i++){
scanf("%s", orders);
}
return 0;
}
There are a number of ways to approach this problem, as indicated by the variety of answers. There is often no one right answer for how to approach a problem in C. The standard library provides a variety of tools that allow you to craft a number of solutions to just about any problem. As long as the code is correct and protects against error, then the choice of which approach to take largely boils down to a question of efficiency. For small bits of example code, that is rarely a consideration.
One approach to take is to recognize that you do not need the first line in your data file (except to read it/discard it to move the file-position-indicator to the start of the first line containing data.)
This allows you to simply use a line-oriented input function (fgets or getline) to read the remaining lines in the file. strtok then provides a simple way to split each line into words (remembering to strip the '\n' or discard the last word in each line). Then it is a small matter of using strcmp to compare each word and multiply by the correct amount. Finally, output the product of the multiplication.
Here is one slightly different approach to the problem. The program will read from the filename given as the first argument (or from stdin by default):
#include <stdio.h>
#include <string.h>
enum { MAXC = 64 };
int main (int argc, char **argv) {
char buf[MAXC] = ""; /* line buffer */
char *delims = " \n"; /* delimiters */
int idx = 0; /* line index */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file pointer */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
while (fgets (buf, MAXC, fp)) { /* read each line */
if (!idx++) continue; /* discard line 1 */
char *p = buf;
size_t len = strlen (p); /* get length */
int prod = 1;
if (len && buf[len-1] == '\n') /* check for '\n' */
buf[--len] = 0; /* remove newline */
printf (" %s", buf); /* output buf before strtok */
/* tokenize line/separate on delims */
for (p = strtok (p, delims); p; p = strtok (NULL, delims))
{ /* make comparson and multiply product */
if (strcmp (p, "Double") == 0) prod *= 2;
if (strcmp (p, "Triple") == 0) prod *= 3;
if (strcmp (p, "Quadruple") == 0) prod *= 4;
}
printf (" = %d\n", prod); /* output product */
}
if (fp != stdin) fclose (fp); /* close file if not stdin */
return 0;
}
Use/Output
$ ./bin/dbltrpl <../dat/dbltrpl.txt
Double Double End = 4
Triple Double End = 6
Quadruple Double Triple End = 24
Look it over and let me know if you have questions.
When it comes to reading the input, you can use strtok with a " " as a parameter to delimite the words you're reading from the input. This is a function filling all of the words read on the input into an array of strings:
PARAMETERS:
char **words: array of strings where you will store all of the words read in the input
char *input: the input you read (i.e. "Double Double end")
char *s: the delimiter you'll use to read words in the input (i.e. " ", "\n")
void getWords(char **words, char *input, char *s){
*words = strtok(str, s);
while(*words){
words++;
*words = strtok(NULL, s);
}
words++;
*words=NULL; //last element will point to NULL
}
Once you have read the words from the input, and filled them inside an array of strings, you could do something like this to calculate the output:
int calculate(char **words){
int result = 1;
while(*words){
if (strcmp(*words, "Quadruple") == 0){
result *= 4;
}else if (strcmp(*words, "Triple") == 0){
result *= 3;
}else if (strcmp(*words, "Double") == 0){
result *= 2;
}else if (strcmp(*words, "End") == 0){
return result;
}
words++;
}
}
Note that you need to correctly initialize the parameters you're passing before calling those functions. Otherwise, it may cause a Segmentation Fault.
You will have to use the methods from the string.h library, such as: strcmp(to compare two strings), strcpy(to copy one string to another) etc. which are generally used when dealing with strings manipulation in c.
Since, we do not know the size of the results array at compile time, we will have to allocate memory to it dynamically. For this purpose I have used malloc and free.
Here is the code to do that:
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main()
{
int num_of_orders, i, j;
char orders[25];
char str1[25];
strcpy(str1,"Double");
char str2[25];
strcpy(str2,"Triple");
char str3[25];
strcpy(str3,"Quadruple");
scanf("%d", &num_of_orders);
getchar();
int *results = malloc(num_of_orders*sizeof(int));
for (i=0; i < num_of_orders; i++)
{
results[i] = 1;
strcpy(orders,"");
while(strcmp(orders,"End") != 0)
{
scanf("%s", orders);
getchar();
if(strcmp(orders,str1)==0)
results[i] *= 2;
else if(strcmp(orders,str2) == 0)
results[i] *= 3;
else if(strcmp(orders,str3)==0)
results[i] *= 4;
}
}
for(i = 0; i < num_of_orders; i++)
printf("%d\n", results[i]);
free(results);
return 0;
}
Note: This program uses strcmp, which does case-sensitive comparison. If you want case-insensitive comparison, then use strcasecmp instead.
Don't forget the fact that the multiplication of integers is commutative:
#include <stdio.h>
#include <string.h>
int main(void)
{
int num_of_orders, i;
char orders[25];
int result;
char *ptr;
scanf("%d", &num_of_orders);
getchar(); // To comsume '\n'
for (i = 0; i < num_of_orders; i++)
{
fgets(orders, sizeof orders, stdin);
result = 1;
ptr = orders;
while(ptr = strstr(ptr, "Double"))
{
result *= 2;
ptr++;
}
ptr = orders;
while(ptr = strstr(ptr, "Triple"))
{
result *= 3;
ptr++;
}
ptr = orders;
while(ptr = strstr(ptr, "Quadruple"))
{
result *= 4;
ptr++;
}
printf("%d\n", result);
}
return 0;
}
What a trivial approach!
Note that strtok() is destructive, namely it will modify order, which can cause some problems if you want to use it later. Also, I think programs using strtok() are less readable. So it might be better to avoid it when possible.

Reverse all strings of several files

I need a program to reverse the order of all strings stored in one or more text files. This is what i've got so far:
#include <stdio.h>
main(int argc, char *argv[])
{
int i;
for (i=1;i < argc;i++)
{
FILE *MyFile=fopen(argv[i], "r");
int i,len;
char str[1000], *ptr;
fgets(str, 1000, MyFile);
ptr = str;
for(i=0;i<1000;i++)
{
if(*ptr == '\0') break;
ptr++;
}
len = i;
ptr--;
for(i=len; i>0; i--)
{
printf("%c",*ptr--);
}
printf("\n");
fclose (MyFile);
}
return 0;
}
What i'm not being able to do is to loop the program correctly so that it reverses all strings. Currently it reverses the first string of all files, but when it encounters a line break the fgets stops. What i've tried to do is to count the lines in the current file, do a for loop, and at the end do another fgets(str, 1000, MyFile); to advance the fgets, but I somehow manage to mess things up.
Another option I thought of is to create a separate function which only reverses a given string, and inside the main function call that function the appropriate number of times, but i'm not sure how to handle the argc and *argv[] in this situation.
Any help? Thanks!
You are clobbering the i variable for the outer loop with another one declared inside. This is most probably why it doesn't work.
You should use strlen() function to get the string length instead of calculating it manually.
Unless you are guaranteed to have strings of at most 1000 bytes, you should consider using a smarter algorithm to cater for longer strings.
Accumulate each char in a buffer until end-of-string (\0) detected. Then print it in reverse.
printf_reverse(const char *buf, size_t len) {
while (len > 0) {
fputc(buf[--len], stdout);
}
}
char buf[1000];
size_t len = 0;
int ch;
while ((ch == fgetc(MyFile)) != EOF) {
if (ch == '\0') {
printf_reverse(buf, len);
len = 0;
}
// You may want not use EOL as part of the reverse
else if (ch == '\n') {
printf_reverse(buf, len);
fputc(ch, stdout);
len = 0;
}
else if (len < sizeof(buf)) {
buf[len++] = ch;
}
else {
; // handle error string too long
}
printf_reverse(buf, len);
OP says "ABCD 1234 Should output: DCBA 4321". In C, a string ends with a \0. It is not clear if the source file has embedded \0 or OP also wants to use a space to indicate the end of the string.

How can I read an input string of unknown length?

If I don't know how long the word is, I cannot write char m[6];,
The length of the word is maybe ten or twenty long.
How can I use scanf to get input from the keyboard?
#include <stdio.h>
int main(void)
{
char m[6];
printf("please input a string with length=5\n");
scanf("%s",&m);
printf("this is the string: %s\n", m);
return 0;
}
please input a string with length=5
input: hello
this is the string: hello
Enter while securing an area dynamically
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(*str)*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(*str)*(size+=16));
if(!str)return str;
}
}
str[len++]='\0';
return realloc(str, sizeof(*str)*len);
}
int main(void){
char *m;
printf("input string : ");
m = inputString(stdin, 10);
printf("%s\n", m);
free(m);
return 0;
}
With the computers of today, you can get away with allocating very large strings (hundreds of thousands of characters) while hardly making a dent in the computer's RAM usage. So I wouldn't worry too much.
However, in the old days, when memory was at a premium, the common practice was to read strings in chunks. fgets reads up to a maximum number of chars from the input, but leaves the rest of the input buffer intact, so you can read the rest from it however you like.
in this example, I read in chunks of 200 chars, but you can use whatever chunk size you want of course.
#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);
input = realloc(input, inputlen+templen+1);
strcpy(input+inputlen, tempbuf);
inputlen += templen;
} 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;
}
Note that this is a simplified example with no error checking; in real life you will have to make sure the input is OK by verifying the return value of fgets.
Also note that at the end if the readinput routine, no bytes are wasted; the string has the exact memory size it needs to have.
I've seen only one simple way of reading an arbitrarily long string, but I've never used it. I think it goes like this:
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);
}
The m between % and s tells scanf() to measure the string and allocate memory for it and copy the string into that, and to store the address of that allocated memory in the corresponding argument. Once you're done with it you have to free() it.
This isn't supported on every implementation of scanf(), though.
As others have pointed out, the easiest solution is to set a limit on the length of the input. If you still want to use scanf() then you can do so this way:
char m[100];
scanf("%99s",&m);
Note that the size of m[] must be at least one byte larger than the number between % and s.
If the string entered is longer than 99, then the remaining characters will wait to be read by another call or by the rest of the format string passed to scanf().
Generally scanf() is not recommended for handling user input. It's best applied to basic structured text files that were created by another application. Even then, you must be aware that the input might not be formatted as you expect, as somebody might have interfered with it to try to break your program.
There is a new function in C standard for getting a line without specifying its size. getline function allocates string with required size automatically so there is no need to guess about string's size. The following code demonstrate usage:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *line = NULL;
size_t len = 0;
ssize_t read;
while ((read = getline(&line, &len, stdin)) != -1) {
printf("Retrieved line of length %zu :\n", read);
printf("%s", line);
}
if (ferror(stdin)) {
/* handle error */
}
free(line);
return 0;
}
If I may suggest a safer approach:
Declare a buffer big enough to hold the string:
char user_input[255];
Get the user input in a safe way:
fgets(user_input, 255, stdin);
A safe way to get the input, the first argument being a pointer to a buffer where the input will be stored, the second the maximum input the function should read and the third is a pointer to the standard input - i.e. where the user input comes from.
Safety in particular comes from the second argument limiting how much will be read which prevents buffer overruns. Also, fgets takes care of null-terminating the processed string.
More info on that function here.
EDIT: If you need to do any formatting (e.g. convert a string to a number), you can use atoi once you have the input.
Safer and faster (doubling capacity) version:
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);
}
Read directly into allocated space with fgets().
Special care is need to distinguish a successful read, end-of-file, input error and out-of memory. Proper memory management needed on EOF.
This method retains a line's '\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;
}
Sample usage
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;
}
I know that I have arrived after 4 years and am too late but I think I have another way that someone can use. I had used getchar() Function like this:-
#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);
}
here is the sample run for this program:-
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
Take a character pointer to store required string.If you have some idea about possible size of string then use function
char *fgets (char *str, int size, FILE* file);
else you can allocate memory on runtime too using malloc() function which dynamically provides requested memory.
i also have a solution with standard inputs and outputs
#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);
}
I have a solution using standard libraries of C and also creating a string type (alias of char*) like in C++
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char* string;
typedef struct __strstr {
char ch;
struct __strstr *next;
}Strstr;
void get_str(char **str) {
char ch, *buffer, a;
Strstr *new = NULL;
Strstr *head = NULL, *tmp = NULL;
int c = 0, k = 0;
while ((ch = getchar()) != '\n') {
new = malloc(sizeof(Strstr));
if(new == NULL) {
printf("\nError!\n");
exit(1);
}
new->ch = ch;
new->next = NULL;
new->next = head;
head = new;
}
tmp = head;
while (tmp != NULL) {
c++;
tmp = tmp->next;
}
if(c == 0) {
*str = "";
} else {
buffer = malloc(sizeof(char) * (c + 1));
*str = malloc(sizeof(char) * (c + 1));
if(buffer == NULL || *str == NULL) {
printf("\nError!\n");
exit(1);
}
tmp = head;
while (tmp != NULL) {
buffer[k] = tmp->ch;
k++;
tmp = tmp->next;
}
buffer[k] = '\0';
for (int i = 0, j = strlen(buffer)-1; i < j; i++, j--) {
a = buffer[i];
buffer[i] = buffer[j];
buffer[j] = a;
}
strcpy(*str, buffer);
// Dealloc
free(buffer);
while (head != NULL) {
tmp = head;
head = head->next;
free(tmp);
}
}
}
int main() {
string str;
printf("Enter text: ");
get_str(&str);
printf("%s\n", str);
return 0;
}

Resources