Sscanf a double value - c

I need scan a double from a string, can you help me? It need to be something like this:
#include <stdio.h>
#include <string.h>
int main()
{
const char *key="infinity";
const char *str = malloc(2*sizeof(double*));
double a;
printf("Write the value: "
scanf("%s",str);
if (strcmp(str,key)==0)
printf ("ok");
else
{
sscanf(str,"%lf",&a);
printf("ok, a is %lf",a);
}
return 0;
When I put infinity, it works properly. But when I enter with some double value (like 1.25), it doesn't.
1.25
ok, a is 0.000000

First all, there is a way you should check if the line of code runs successfully or not.
You are using sscanf(), check it's return value to be sure if it is being successful in what it is supposed to do. (To get the double from str).
Also why const char*. It is pointing to an immutable character string. You can't change it's value. So the first scanf will fail. You can simply use char* here, that will be sufficient for your requirement.
Allocating 2*sizeof(double*) doesn't ensure that you will be able to hold all the digits of a double number. That's a wrong idea. You can consider a rough value to hold (like upto 12 digits after decimal point) and then scan it.
Considering the return value of malloc is another good practice. In case it fails it returns NULL. And after getting NULL if you go on accessing it, then it invokes undefined behavior.
Whatever you allocate using malloc, it's need to be freed after you are done working with it.
Also read some good books. There are plenty of them.
A small example:
#include <stdio.h>
#include <string.h>
#include <float.h>
#include <stdlib.h>
#include <ctype.h>
char *trimwhitespace(char *str)
{
char *end;
while(isspace((unsigned char)*str)) str++;
if(*str == 0)
return str;
end = str + strlen(str) - 1;
while(end > str && isspace((unsigned char)*end)) end--;
*(end+1) = 0;
return str;
}
int main()
{
const char *key="infinity";
char *str = malloc(sizeof(char)*(3 + DBL_MANT_DIG - DBL_MIN_EXP+1));
if( str == NULL){
fprintf(stderr,"Error in malloc");
exit(1);
}
char *store = str;
double a;
printf("Write the value: ");
if( fgets(str, (3 + DBL_MANT_DIG - DBL_MIN_EXP+1), stdin) == NULL){
fprintf(stderr,"Error in string input");
exit(1);
}
str = trimwhitespace(str);
if( strlen(str) == 0){
printf("Empty line detected.\n");
return EXIT_FAILURE;
}
for(size_t i = 1; i < strlen(str); i++){
if( !isspace(str[i]) && isspace(str[i-1])){
printf("Error extra input detected\n");
return EXIT_FAILURE;
}
}
if (strcmp(str,key)==0)
printf ("ok");
else
{
char *err;
a = strtod(str, &err);
if (*err!=0 && !isspace((unsigned char)*err)) {
printf("Error extra input detected ");
}
else{
printf("ok, a is %lf",a);
}
}
free(store);
return 0;
}
Reference:
† After finding a bit I could finally cite the correct reference for the 3 + DBL_MANT_DIG - DBL_MIN_EXP part. Check this answer.

Related

Longest word in file

My program needs to print longest word which contains only letters from a file.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int checkString(const char s[]) {
unsigned char c;
while ((c = *s) && (isalpha(c) || isblank(c)))
++s;
return *s == '\0';
}
int main() {
char file_name[]="document.txt";
FILE *fp = fopen(file_name, "r");
char *largest = str;
int largest_len = 0;
while (fgets(file_name, 1000, fp) != NULL) {
char *temp = strtok(file_name, " ");
while (temp != NULL) {
if (strlen(temp) > largest_len) {
strcpy(largest, temp);
largest_len = strlen(largest);
}
temp = strtok(NULL, "\",.,1,2,4,5,6,7,8,9 ");
}
}
if(checkString(largest))
printf("%s", largest);
fclose(fp);
return 0;
}
In my code, if the largest word contains only letters it will be printed. How to modify this code to check next words if the largest doesn't contain only letters?
First of all, you cannot store the pointer to longest word like that. You re-use str for the next line and so the pointer is not likely to point to something useful.
Second, while strtok() appears simple, initially, I tend to apply a straightforward approach to a straightforward problem.
The problem is O(n) (where n is the length of the document). You just need to go through it character by character. Of course, since every line is ended by a \n, you can use the line based approach in this case.
So, instead of strtok, simply check each character, if it is a legal word character (an alphanumeric character, that is). You can easily do so with the standard library function isalpha() from header ctype.h.
Below is the program, copying the longest string into a dedicated buffer, using isalpha() and doing the line based reading of the file, just like the code in the original question did.
Of course, this code assumes, no line is ever longer than 999 characters.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <ctype.h>
static size_t gulp(const char* line, size_t istart, size_t len) {
size_t n = 0;
for (size_t i = istart; i < len; i++, n++) {
if (!isalpha(line[i])) {
break;
}
}
return n;
}
int main(int argc, const char * argv[]) {
FILE* f = fopen("document.txt","r");
char line[1000];
char longest_word[1000];
size_t longest_word_length = 0;
while (fgets(line, sizeof(line), f) != NULL) {
size_t i0 = 0;
size_t line_length = strlen(line);
while (i0 < line_length) {
if (isalpha(line[i0])) {
size_t n = gulp(line, i0, line_length);
if (n > longest_word_length) {
strncpy(longest_word, &line[i0], n);
longest_word[n] = '\0';
longest_word_length = n;
}
i0 = i0 + n;
} else {
i0++;
}
}
}
fclose(f);
f = NULL;
if (longest_word_length > 0) {
printf("longest word: %s (%lu characters)\n",
longest_word, longest_word_length);
}
return 0;
}
There are a number of problems here:
you use the same buffer (str) for two different uses: as a read buffer and to store the longest word. If you find the largest word in the first line, the word will be erased when reading the second line. Furthemore, if you find a rather long word at the beginning of a line, the strings pointed to by largest and temp could overlap which leads to undefined behaviour => use a different array or strdup (and free) for largest
you only use the space as possible separator. You should wonder whether you should add tab and/or punctuations
once you have got a word you should ensure that it only contains valid letters before testing its length and ignore it if for example it contains digits.
if a single line can be longer than 1000 characters, you should wrap the end of the current part before the beginning of the next one for the possible case where a long word would be splitted there.
For additional corner case processing, you should specify what to do if a word contains illegal characters but only at one side. For example if . is not used as a word delimiter, a word with an embedded . like "a.b" should be ignored, but a terminating . should only be stripped (like "example." should become "example"
I think the order you do things should be a bit different, here is an example
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int isCandidate(char* word);
int main(int argc, char* argv[])
{
if (--argc == 0)
{
perror("not enough command line arguments, expecting a filename");
return -1;
}
++argv;
FILE* fp = fopen(*argv, "r");
if (fp == NULL)
{
perror(*argv);
return -1;
}
// get size of file
fseek(fp, 0L, SEEK_END);
long fileLength = ftell(fp);
if (fileLength < 1)
{
perror("file is empty");
return -1;
}
fseek(fp, 0L, SEEK_SET); // position file pointer at the beginning again
// allocate space for the whole file and then read it in
// for a text file it should be OK to do so since they
// normally are not that large.
char* buffer = malloc(fileLength+1);
if (fread(buffer, 1, fileLength, fp) != 0)
{
buffer[fileLength] = '\0'; // make sure the buffer ends with \0
}
else
{
perror("Failed reading into buffer");
return -1;
}
fclose(fp); // we are done with the file
const char filter[] = " \n\r";
char* longestWord = malloc(fileLength+1); // max length in theory
long unsigned int maxLength = 0;
for (char* token = strtok(buffer, filter); token != NULL; token = strtok(NULL, filter))
{
if (isCandidate(token))
{
if (strlen(token) > maxLength)
{
strcpy(longestWord, token);
maxLength = strlen(token);
}
}
}
printf("Longest word:'%s', len=%lu\n", longestWord, maxLength);
free(longestWord);
free(buffer);
}
int isCandidate(char* word)
{
if (word == NULL)
{
perror("invalid argument to isCandidate");
return 0;
}
for (char* ch = word; *ch; ++ch)
{
if (!isalpha(*ch)) return 0;
}
return 1;
}

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.

Dynamic string array in C with malloc and realloc won't exit a loop

I've been trying to make a simple console application in C (using dev-c++) that reads characters and places them in an array while dynamically lengthening the array to accomodate for as many characters as you want until you press enter. The code is this:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
main()
{
int x=0;
char * ch1;
ch1 = (char*) malloc(1);
do
{
ch1[x] = getche();
x++;
ch1 = (char*) realloc (ch1,x);
} while (ch1[x-1]!='\n');
printf("Input Sentence Is :%s",ch1);
free(ch1);
}
while the program executes fine with no errors, after you type your sentence and press enter instead of simply printing your sentence the 'cursor' shifts back to the begining of the window and you can keep typing above the previous characters.
Edit: I know this is not an optimal way to do it since you lose the backspace ability for example i just wanted to see if it would work after we were taught malloc and realloc today.
I'm all-but-certain this is what you're trying to do. The difference between it and your code should be obvious:
Uses calloc() for the initial buffer to ensure it is terminated,
Checks for input stream EOF as well as CR and LF chars.
x represents the buffer length, not the string length.
String termination is established on each successful expansion.
Memory allocation failures are accounted.
Standard-compliant declaration of main(),
Uses the standard-compliant getchar() for input.
Code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *ch1 = calloc(1,1), *tmp;
size_t x = 1;
int c;
if (!ch1)
{
perror("Failed to allocate string buffer.");
exit(EXIT_FAILURE);
}
while ((c = getchar()) != EOF && c != '\r' && c != '\n')
{
tmp = realloc(ch1, x+1);
if (!tmp)
{
// note: the string at ch1 still valid.
perror("Failed to resize string buffer.");
break;
}
ch1 = tmp;
ch1[x - 1] = c;
ch1[x++] = 0;
}
printf("Input Sentence: %s\n", ch1);
free(ch1);
return 0;
}
Hope it helps.
On my current system (SUSE SLES-11) I can't compile this due to the non-portable conio.h. Here's my solution;
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <errno.h>
int main()
{
int rCode = 0;
char *buf = NULL;
size_t bufSize = 0;
int done = 0;
/* Allocate a single byte to hold a string-termination
* character '\0'
*/
errno=0;
buf = malloc(bufSize + 1);
if(NULL == buf)
{
rCode=errno?errno:ENOMEM;
fprintf(stderr, "malloc() failed. errno=%d\n", errno);
goto CLEANUP;
}
++bufSize;
buf[0] = '\0';
/** Loop until done. **/
while(!done)
{
char *tmp; /* Used to safely realloc(). */
int ch = getche(); /* read the next character. */
switch(ch)
{
case '\r': /* Check for end-of-line characters. */
case '\n': /* (I agree with Paul Z's comment. */
done = (-1); /* TRUE */
/* Do not include these characters in the final buffer. */
continue;
default:
/* Change the last character of the buf from '\0' to ch. */
buf[bufSize] = ch;
/* Increase the size of buf so that a new '\0' character can
* be appended.
*/
errno=0;
tmp=realloc(buf, bufSize+1);
if(NULL == tmp)
{
rCode=errno?errno:ENOMEM;
fprintf(stderr, "realloc() failed. errno:%d\n", errno);
goto CLEANUP;
}
buf=tmp; // EDIT (Thanks Floris for catching this!)
buf[bufSize++] = '\0';
break;
}
}
printf("Input Sentence Is: %s\n", buf);
CLEANUP:
if(buf)
free(buf);
return(rCode);
}

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