I am trying to read sentence from user input problem with my function is it skips second try when I try to call it. Any solution?
void readString(char *array, char * prompt, int size) {
printf("%s", prompt);
char c; int count=0;
char * send = array;
while ((c = getchar()) != '\n') {
send[count] = c; count++;
if (size < count){ free(array); break; } //lets u reserve the last index for '\0'
}
}
Here is how try to call it:
char obligation[1500];
char dodatno[1500];
readString(obligation, "Enter obligation", 1500);
readString(dodatno, "Enter hours", 1500);
Here is example of inputs:
"This is some sentence"
so latter I wana do this:
printf(" %s | %s \n",obligation, dodatno);
and get:
This is some sentence|This is another sentence
In your readString() function,
array is not allocated memory dynamically, by malloc() or family.
Calling free() with a pointer not allocated memory dynamically creates undefined behavior.
getchar() returns an int. You should change the type of c to int c.
Also, there is no null-termination of your input in readString(), so you cannot directly use the arrays as string. You need to null-terminate the arrays yourself, used as read buffer to be used as a string later.
There you go :)
void readString(char *array, char * prompt, int size) {
printf("%s", prompt);
int c; int count=0;
while((c = getchar()) != '\n' && c != EOF);
while ((c = getchar()) != '\n') {
array[count] = c; count++;
if (count == (size - 1)) { break; }
}
array[count] = '\0';
}
Related
I need some help regarding dynamic allocation of arrays of pointers in C. I am trying to create a program that reads a sentence of words from user input, and stores the words in character array strings. I then want to save the pointers char *word to these words in an array of pointers char **wordArray.
Creating a working method for dynamic allocation for the words was easy enough, and it reads character by character from user input. However, trying to adapt this method for the array of pointers was trickier.
The current function char **varArray is obviously flawed, but my thinking was "while the user has input, get words pointers for the array of pointers". It now effectively loops the first word for every char c.
My question is, how do I implement a second layer (char **varArray()) of dynamic memory allocation of my array of pointers? How can the function detect when to call char *word()?
Feedback for the code, style, or other errors are of course appreciated. My level is intermediate beginner.
/*CREATES AND ALLOCATES DYNAMIC VARIABLE ARRAY*/
#include <stdio.h>
#include <stdlib.h>
char **varArray();
char *word();
char **varArray()
{
char **tmp=NULL;
char **wordArray=NULL;
size_t size=0;
char c = EOF;
int words=0;
while(c) {
c=getc(stdin);
if (c == EOF || c == '\n')
c=0;
if (size <= words) {
size+=sizeof(char *);
tmp = realloc(wordArray,size);
if(tmp == NULL) {
free(wordArray);
wordArray=NULL;
printf("Memory allocation failed. Aborted.\n");
break;
}
wordArray=tmp;
}
words++;
wordArray[words]= word();
return wordArray;
}
The method for retrieving ONE word:
/*GETS ONE WORD FROM USER INPUT*/
char *word()
{
char *word=NULL, *tmp=NULL;
size_t size=0;
char c = EOF;
int letters=0;
while(c) { //reads character by character
c=getc(stdin);
if (c == EOF || c == '\n' || c==' ') //remove ' ' to read all input
c =0;
if (size <= letters) { //increase and reallocate memory
size = size + sizeof(char);
tmp = realloc(word,size);
if (tmp==NULL) { //check if allocation failed
free(word);
word=NULL;
printf("Memory allocation failed. Aborted.\n");
break;
}
word= tmp;
}
letters=letters+1;
word[letters]=c;
}
/*ADD SENTINEL CHARACTER*/
letters++;
size += sizeof(char);
word = realloc(word,size);
word[letters]='\n';
return word;
}
Here's the skeleton of the program you want to write.
...
char* currentWord;
char **wordArray=NULL;
while ((currentWord = word()) != NULL) {
.... add current word to word array with realloc...
}
....
char* word() {
int ch;
char* outputWord = NULL;
while ((ch = getch()) != EOF) {
if ( ... ch is a word character ... )
... add ch to output word with realloc ...
else {
char* ret = outputWord;
outputWord = NULL;
return ret;
}
}
return NULL;
}
Note how the two while loops are doing exactly the same thing.
while ((element = getNextElement()) != sentinelValue) {
.... process newly obtained element ....
}
I have now successfully implemented a version of the shell provided by #n.m. However, another problem arose - since word() relies on the sentinel newline character \n to quit, it also fails to read the final word, and does not enter the loop the last, vital time.
I have tried to implement some if-cases, but these of course fail due to the while-condition. Another idea would be to implement some switch case, but I am not sure that would avoid the nastiness of the while loop?
Do note that the code has little error checking to minimise the clutter.
char **wordArray() {
char *currentWord;
char **wordArray=NULL;
size_t size=0;
int i=0;
while((currentWord = word()) != NULL) {
size+=sizeof(char *);
wordArray=(char **) realloc(wordArray,size);
wordArray[i]=currentWord;
printf("Test - Current word: %s\n",currentWord);
i++;
}
return wordArray;
}
The relevant word() function:
char *word() {
char ch;
int i=0;
size_t size=0;
char *returnWord = NULL;
char *outputWord = NULL;
char *tmp = NULL;
while((ch = getc(stdin)) != EOF && ch !='\n') { //&& ch !='\n'
if (ch != ' ' ) { //&& ch !='\n'
size += sizeof(char);
tmp = (char *) realloc(outputWord,size);
outputWord= tmp;
outputWord[i]=ch;
printf("Test1: %c\n",*(outputWord+i));
i++;
} else {
printf("Test2: %s\n",outputWord);
returnWord=outputWord;
outputWord=NULL;
printf("Test3: %s\n",returnWord);
return returnWord;
}
}
return NULL;
}
Hi im trying to read user input of "unlimited" length into an char array. It works fine for shorter strings, but for more than around 30 characters the programm crashes. Why does this happen and how can i fix this?
#include <stdio.h>
#include <stdlib.h>
char* read_string_from_terminal()//reads a string of variable length and returns a pointer to it
{
int length = 0; //counts number of characters
char c; //holds last read character
char *input;
input = (char *) malloc(sizeof(char)); //Allocate initial memory
if(input == NULL) //Fail if allocating of memory not possible
{
printf("Could not allocate memory!");
exit(EXIT_FAILURE);
}
while((c = getchar()) != '\n') //until end of line
{
realloc(input, (sizeof(char))); //allocate more memory
input[length++] = c; //save entered character
}
input[length] = '\0'; //add terminator
return input;
}
int main()
{
printf("Hello world!\n");
char* input;
printf("Input string, finish with Enter\n");
input = read_string_from_terminal();
printf("Output \n %s", input);
return EXIT_SUCCESS;
}
realloc(input, (sizeof(char))); //allocate more memory only allocates 1 char. Not 1 more char. #MikeCAT
(sizeof(char)*length+1) is semantically wrong. Should be (sizeof(char)*(length+1)), but since sizeof (char) == 1, it makes no functional difference.
Need space for the null character. #MikeCAT
Should test for reallocation failure.
char c is insufficient to distinguish all 257 different responses from getchar(). Use int. getchar() may return EOF. #Andrew Henle
Minor: Better to use size_t for array indexes than int. int maybe too narrow.
In the end code needs to do something like:
size_t length = 0;
char *input = malloc(1);
assert(input);
int c;
...
while((c = getchar()) != '\n' && c != EOF) {
char *t = realloc(input, length + 1);
assert(t);
input = t;
input[length++] = c;
}
...
return input;
int main(void) {
...
input = read_string_from_terminal();
printf("Output \n %s", input);
free(input);
return EXIT_SUCCESS;
}
So I have been trying to read input string and then print it by not using neither scanf() nor printf() but getchar() and putchar() instead.
It seems like the program is stuck in the loop, I'm not able to spot an error.
#include <stdio.h>
void getstring(char *c)
{
char inS[100];
char n;
int i = 0;
while ((n = getchar()) != '\n') {
inS[i] = n;
i++;
}
inS[i] = '\0';
i = 0;
while (inS[i] != '\0') {
putchar(inS[i]);
i++;
}
}
main()
{
char *prompt;
prompt = "Enter a sentence: \n";
getstring(&prompt);
printf("%s", prompt);
}
Your code has some problems. Here is the corrected code:
#include <stdio.h>
void getstring(void) /* You don't use the passed argument. So, I've removed it */
{
char inS[100];
/* `char n;` getchar() returns an int, not a char */
int n;
int i = 0;
while (i < 99 && (n = getchar()) != '\n' && n != EOF) /* Added condition for preventing a buffer overrun and also for EOF */
{
inS[i] = n;
i++;
}
inS[i] = '\0';
putchar('\n'); /* For seperating input and output in the console */
i = 0;
while (inS[i] != '\0')
{
putchar(inS[i]);
i++;
}
putchar('\n'); /* For cleanliness and flushing of stdout */
}
int main(void) /* Standard signature of main */
{
char *prompt;
prompt = "Enter a sentence: \n";
printf("%s", prompt); /* Interchanged these two lines */
getstring(); /* Nothing to pass to the function */
return 0; /* End main with a return code of 0 */
}
Note: The loop for input will end when either
A \n(Enter) has been encountered.
An EOF has been encountered.
99 characters were read from stdin.
Maybe you are not adding \n in your stdin? Executing your code was successful. Also you are not modifying passed char *c, why? And to modify a pointer you should pass a pointer to a pointer (How do I modify a pointer that has been passed into a function in C?)
First you can make all the elements of the array to NULL.
char inS[100] = {"\0",};
You can use gets() to get the string from the console. some thing as below.
your code
while ((n = getchar()) != '\n') {
inS[i] = n;
i++;
}
Modify it as:
gets(inS);
Then you can do the other operation what ever you want.
getchar replaces \n character with \0 whenever it sees a newline character. So n will never be \n.
You should try getc or fgetc.
You are not printing a new line. After putchar(ch) you should use putchar('\n') to print a new line
#include <stdio.h>
void getstring(char *c)
{
char n;
int i = 0;
while ((n = getchar()) != '\n')
{
*c=n;
c++;
}
c = '\0';
main()
{
char inS[100];
char *prompt=inS;
getstring(prompt);
printf("%s", prompt);
}
strong text
In main() function only pointer is declared but it is not assigned to any symbol in other words pointer declared but it does not refer to any memory location. That problem is solved in this solution
After verifying that strcat is where the error occurs, I then check the previous example in my assignment. In my previous examples I use strcat(actually strncat) in the same fashion as I do for my following code. I am not too sure.
The purpose of my program is to loop through "string" and remove any occurances the character 'c' from string.
main.c:
char string[100]={0}, c[3];
printf("Enter a String: ");
fgets(string, 100, stdin);
if (string[98] == '\n' && string[99] == '\0') { while ( (ch = fgetc(stdin)) != EOF && ch != '\n'); }
printf("Enter a Char: ");
fgets(c, 2, stdin);
while ( (ch = fgetc(stdin)) != EOF && ch != '\n');
rmchr(string, c[0]);
header:
rmchr(char *string, char c)
{
int i=0;
char *word[100];
int s = strlen(string);
for(i=0; i<=(s-2); i++)
{
if(string[i] != c)
{
strcat(word, string[i]);
}
}
}
char *word[100];
It will hold a string in your program so use:
char word[100];
that is, an array of char instead of an array of char *.
Then strcat concatenates to a string but word is not initialized. Make it a string with:
word[0] = '\0';
Then string[i] is a character but strcat needs pointers to character arguments: to use a pointer use &string[i].
Finally the problem in your rmchr function is it has to return something, either through the arguments or via a return statement but it doesn't.
There are more than one point to mention here, like
rmchr() definition should have a return type, maybe void if you're not returning anything.
[FWIW, In that case, I wounder, how you'll make use of the local variable word]
inside rmchr(), word needs to be an array of chars, not char pointers. You need to change char * word[100] to char word[100].
In strcat(), both the arguments, needs to be a pointer. You need to use &string[i], in that case.
The following seems to compile fine but your code doesnt do quite what you said you wanted, "The purpose of my program is to loop through "string" and remove any occurances the character 'c' from string.". the function doesn't remove the character or return a copy of the string with the character excluded. I wrote a function that copies the string after removing the character and returns pointer to it. below is your code a bit modified and under it is my function
//Just a compilable version of your code, not sure if it does what u want
#include <stdio.h>
#include <string.h>
void rmchr(char *string, char c)
{
int i=0;
char word[100];
int s = (int)strlen(string);
for(i=0; i<=(s-2); i++)
{
if(string[i] != c)
{
strcat(word, (char *)(&string[i]));
}
}
}
int main(int argc, const char * argv[]) {
char string[100] = {0}, c[3];
char ch;
printf("Enter a String: ");
fgets(string, 100, stdin);
if (string[98] == '\n' && string[99] == '\0') {
while ( (ch = fgetc(stdin)) != EOF && ch != '\n');
}
printf("Enter a Char: ");
fgets(c, 2, stdin);
while ( (ch = fgetc(stdin)) != EOF && ch != '\n');
rmchr(string, c[0]);
return 0;
}
There you go, with a demo main
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* rmchr(char *string, char ch)
{
int counter = 0;
int new_size = 0;
char corrected_string[100];
while (string[counter] != '\n' && string[counter] != '\0' && string[counter] != EOF) {
if (string[counter] != ch) {
corrected_string[new_size] = string[counter];
new_size++;
}
counter++;
}
char *new_string = (char *)malloc((new_size+1) * sizeof(char));
for (int j = 0; j <= new_size; j++) {
new_string[j] = corrected_string[j];
}
return new_string;
}
int main(int argc, const char * argv[]) {
char *s = "The char 'c' will be removed";
char *new = rmchr(s, 'c');
printf("%s", new);
return 0;
}
I am trying to allocate a dynamic string by accepting it from user. I want to do it using a function. I am trying to implement the following code, but it is not working properly.
#include<stdio.h>
#include<stdlib.h>
int string(char *str)
{
char c;
int i=0,j=1;
str = (char*)malloc(sizeof(char));
printf("Enter String : ");
while(c!='\n')
{
c = getc(stdin); //read the input from keyboard standard input
//re-allocate (resize) memory for character read to be stored
*str = (char*)realloc(str,j*sizeof(char));
*str[i] = c; //store read character by making pointer point to c
i++;
j++;
}
str[i]='\0'; //at the end append null character to mark end of string
printf("\nThe entered string is : %s",str);
return j;
}
int main()
{
int len;
char *str=NULL;
len=string(str);
printf("\nThe entered string is : %s and it is of %d length.",str,len);
free(str);
return 0;
}
A number of issues:
memory size is one too small.
while(c!='\n') first test c even though it is uninitialized.
string() should pass the address of a char * as in string(char **)
Better to use size_t rather than int when working with strlen().
Minor:
EOF is not detected. Use int c rather than char c to aid in detection.
Certainly inefficient to realloc() each loop.
Casting of malloc()/realloc() unnecessary.
Good to check for out-of-memory.
Use int main(void) rather than int main() for portability.
size_t string(char **str) {
assert(str);
int c;
size_t i = 0;
size_t size = 0;
*str = NULL;
printf("Enter String : ");
while((c = getc(stdin)) !='\n' && c != EOF) {
if (i == size) {
size *= 2 + 1; // double the size each time
*str = realloc(*str, size);
assert(*str);
}
(*str)[i] = c; // store read character by making pointer point to c
i++;
}
*str = realloc(*str, i+1); // right-size the string
assert(*str);
(*str)[i] = '\0'; // at the end append null character to mark end
printf("\nThe entered string is : %s",*str);
return i;
}
You need to pass a referejce to a pointer (int string(char **str)) because you're changing the value of str inside the function.
In main you should call string(&str)