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
Related
When I am using gets() to scan input it is working perfectly ,but when I'm using fgets() to scan the input then the answer is coming out as 1 more than the actual length.
For example:--> For input "Hello"
fgets() is printing 6. BUT the answer should be 5.
Why? How to resolve
#include <stdio.h>
#include <string.h>
int string_length(char str[]);
int main()
{
char str[100];
printf("**********************************************\n");
printf("This is a program to reverse a string.\n");
printf("**********************************************\n");
printf("Enter a string: ");
fgets(str,100,stdin); // ----> when using this fgets() answer of length of string is coming out to be one more than the actual answer
gets(str); //This is giving the correct answer if used instead of fgets().
printf("%d",string_length(str));
return 0;
}
//function for calculating string length
int string_length(char str[])
{
int i;
for(i=0; str[i]!='\0'; i++);
return i;
//WAY__2
//OR by while loop
// int i,length=0;
// while (str[length] != '\0')
// {
// length ++;
// }
// return length;
//WAY__3
//OR by using strlen() function;
// int length = strlen(str);
// return length;
}
The function fgets can append the new line character '\n' to the entered sequence of characters. You should remove it as for example
str[ strcspn( str, "\n" ) ] = '\0';
As for the function gets then it is unsafe and is not supported by the C Standard. You should not use it.
As for your function string_length then it should be declared like
size_t string_length( const char str[] );
fgets reads also \n character from the file/stream. You need to remove it.
char *removeNL(char *str)
{
char *wrk = str;
if(wrk)
{
while(*wrk && *wrk != '\n' ) wrk++;
*wrk = 0;
}
return str;
}
Also use the correct type for sizes (size_t)
size_t string_length(const char *str)
{
size_t i;
for(i=0; str[i]!='\0'; i++);
return i;
}
You do not need the counter as you can use the pointer arithmetic to get the string length:
size_t string_length1(const char *str)
{
const char *end = str;
while(*end) end++;
return end - str;
}
I had to rewrite two functions as per two exercises in a book I'm working from. One that simply reads a line of characters, readLine and another that compared two character strings and returned either 1 or 0 based on whether they match, 'equalStrings`.
The point of the exercise was to rewrite the functions so they used pointers, as opposed to arrays.
I've been struggling with prior exercises and was surprised how quickly I was able to do this so I'm concerned I'm missing something important.
Both programs compile and run as hoped though.
This is the original readLine function:
#include <stdio.h>
void readLine(char buffer[]);
int main(void)
{
int i;
char line[81];
for(i = 0; i < 3; i++)
{
readLine(line);
printf("%s\n\n", line);
}
return 0;
}
void readLine(char buffer[])
{
char character;
int i = 0;
do
{
character = getchar();
buffer[i] = character;
i++;
}
while(character != '\n');
buffer[i - 1] = '\0';
}
My edited with pointers:
#include <stdio.h>
void readLine(char *buffer);
int main(void)
{
int i;
char line[81];
char *pointer;
pointer = line;
for(i = 0; i < 3; i++)
{
readLine(pointer);
printf("%s\n\n", line);
}
return 0;
}
void readLine(char *buffer)
{
char character;
int i;
i = 0;
do
{
character = getchar();
buffer[i] = character;
i++;
}
while(character != '\n');
buffer[i - 1] = '\0';
}
Here is the original equalString function:
#include <stdio.h>
#include <stdbool.h>
bool equalStrings(const char s1[], const char s2[]);
int main(void)
{
const char stra[] = "string compare test";
const char strb[] = "string";
printf("%i\n", equalStrings(stra, strb));
printf("%i\n", equalStrings(stra, stra));
printf("%i\n", equalStrings(strb, "string"));
return 0;
}
bool equalStrings(const char s1[], const char s2[])
{
int i = 0;
bool areEqual;
while(s1[i] == s2[i] && s1[i] != '\0'){
i++;
if(s1[i] == '\0' && s2[i] == '\0')
areEqual = true;
else
areEqual = false;
}
return areEqual;
}
and the rewritten with pointers:
#include <stdio.h>
#include <stdbool.h>
bool equalStrings(const char *pointera, const char *pointerb);
int main(void)
{
const char stra[] = "string compare test";
const char strb[] = "string";
const char *pointera;
const char *pointerb;
pointera = stra;
pointerb = strb;
printf("%i\n", equalStrings(pointera, pointerb));
printf("%i\n", equalStrings(pointerb, pointerb));
printf("%i\n", equalStrings(strb, "string"));
return 0;
}
bool equalStrings(const char *pointera, const char *pointerb)
{
int i = 0;
bool areEqual;
while(pointera[i] == pointerb[i] && pointera[i] != '\0'){
i++;
if(pointera[i] == '\0' && pointerb[i] == '\0')
areEqual = true;
else
areEqual = false;
}
return areEqual;
}
Is there anything glaring out that needs to be changed?
Thank you.
There are (3) conditions you need to protect against in your readline function. (1) you must protect against writing beyond the end of your array. Utilizing a simple counter to keep track of the number of characters added will suffice. You can express this limit in your read loop. Your array size is 81 (which will hold a string of 80 characters +1 for the nul-terminating character. Assuming you create a #define MAXC 81 for use in your code, your first condition could be written as:
void readline (char *buffer)
{
int i = 0, c;
while (i + 1 < MAXC && ...
(2) the second condition you want to protect against is reaching a '\n' newline character. The second condition for your read loop could be written as:
while (i + 1 < MAXC && (c = getchar()) != '\n' && ...
(3) the third condition you must protect against is encountering EOF with a line before a newline character is reached (many editors produce files with non-POSIX line-endings). With the final condition, your complete set of test conditions could look like the following:
while (i + 1 < MAXC && (c = getchar()) != '\n' && c != EOF)
(and that is why c must be signed (and should be a signed int), because EOF is generally -1)
Putting that together, with what it appears was intended in rewriting the function from using array-index notation to using pointer notation, you could do something like the following:
void readline (char *buffer)
{
int i = 0, c;
while (i + 1 < MAXC && (c = getchar()) != '\n' && c != EOF) {
*buffer++ = c;
i++;
}
*buffer = 0;
if (i + 1 == MAXC && *(buffer - 1) != '\n')
fprintf (stderr, "warning: line truncation occurred.\n");
}
You should also check, as shown above, whether you read all the characters in the line, or whether a short-read occurred (meaning after reading 80 allowable characters, there were still more characters in the line to be read, but to prevent writing beyond the end of your array, and leaving room for the terminating nul, you stopped reading before your reached the newline). You are free to handle it as you like, but be aware -- those characters still exist in the input buffer (stdin here) and will be the very next characters read on your next call to getchar(). So you may want a way to tell if that occurred.
Putting the function together in a short example with a helpful input file will help explain.
#include <stdio.h>
#define MAXC 81
void readline(char *buffer);
int main(void) {
int i;
char line[MAXC] = "", *pointer = line;
for(i = 0; i < 3; i++) {
readline (pointer);
printf ("%s\n\n", line);
}
return 0;
}
void readline (char *buffer)
{
int i = 0, c;
while (i + 1 < MAXC && (c = getchar()) != '\n' && c != EOF) {
*buffer++ = c;
i++;
}
*buffer = 0;
if (i + 1 == MAXC && *(buffer - 1) != '\n')
fprintf (stderr, "warning: line truncation occurred.\n");
}
How will your function behave if given a 90 character line to read?
Input File
Two lines with 90 characters each.
$cat dat/90.txt
123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
Example Use/Output
Note what has occurred. On the first read attempt, 80 character were read, and a short read occurred. You were warned of that fact. The second read, read the reamining 10 characters in the first line (chars 81-90). The third, and final, read, again reads the first 80 chars of the second line and the code terminates.
$ ./bin/getchar_ptr <dat/90.txt
warning: line truncation occurred.
12345678901234567890123456789012345678901234567890123456789012345678901234567890
1234567890
warning: line truncation occurred.
12345678901234567890123456789012345678901234567890123456789012345678901234567890
I'll let you look this over and incorporate any of the suggestions you find helpul in the rest of your code. Let me know if you have any questions. Make sure you fully undetstand what is being passed as buffer in void readline (char *buffer) (copy as opposed to original) as basic pointer understandin has implications throughout C.
I need a simple function that can read multiple words into a string in C, kind of like Scanner.nextLine() in Java or Console.ReadLine() in C#, but I can't seem to find a simple method anywhere, I tried all sorts of things, but none of them seem to work 100% of the time.
You can use fgets
char *fgets(char *str, int n, FILE *stream)
Be aware that fgets reads until reach the size n, or a newline or an EOF.
This is made to avoid buffer overflow, so you need to make sure that your buffer is big enough to store the string.
scanf is what you want:
#include <stdio.h>
int main(void)
{
char string[50];
scanf(" %49[^\n]s",string);
printf("you entered: %s\n",string);
}
you can follow this:
char str[100];// as length of the total words neded
fgets(str,100,stdin)
printf("output: %s",str);
return 0;
Use fgets to parse an input string into a char buffer.
char * fgets ( char * str, int num, FILE * stream );
Here is the link for a better description
Then use sscanf to dissect this string to however you need it.
int sscanf ( const char * s, const char * format, ...);
Here is the link for a better description
This removes the '\n' character that is included in the string returned by fgets, thus making the function practically equivalent to the functions present in popular managed languages:
//gets a line from the specified stream
int getline(char* charArray, int maxLength, FILE* stream) {
int i;
if (fgets(charArray, maxLength, stream) == NULL)
return 1; //some error occurred
for (i = 0; i < maxLength; i++) {
if (charArray[i] == '\n') {
if (i != 0 && charArray[i - 1] == '\r') //cater for windows line endings
i--;
charArray[i] = '\0';
return 0; //all's well that ends well
} else if (charArray[i] == '\0')
return 0; //smooth sailing fam
}
return 2; //there was no string terminator
}
Here you go:
#include "stdio.h"
//gets a line from the specified stream
int getline(char* charArray, int maxLength, FILE* stream) {
int i;
if (fgets(charArray, maxLength, stream) == NULL)
return 1; //some error occurred
for (i = 0; i < maxLength; i++) {
if (charArray[i] == '\n') {
if (i != 0 && charArray[i - 1] == '\r') //cater for windows line endings
i--;
charArray[i] = '\0';
return 0; //all's well that ends well
} else if (charArray[i] == '\0')
return 0; //smooth sailing fam
}
return 2; //there was no string terminator
}
int main() {
char money[4];
printf("How much money do you have on you? ");
getline(money, 4, stdin);
printf("Oh really? $%d? Good. :)\n", atoi(money));
char string[4];
printf("Where is our next lesson?\n");
getline(string, 4, stdin);
printf("%s", string);
return 0;
}
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';
}
How do I fill an 80-character buffer with characters as they are being entered or until the carriage return key is pressed, or the buffer is full, whichever occurs first.
I've looked into a lot of different ways, but enter has to be pressed then the input char* gets cut off at 80..
Thanks.
If you really want the characters "as they are entered", you cannot use C io. You have to do it the unix way. (or windows way)
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
int main() {
char r[81];
int i;
struct termios old,new;
char c;
tcgetattr(0,&old);
new = old;
new.c_lflag&=~ICANON;
tcsetattr(0,TCSANOW,&new);
i = 0;
while (read(0,&c,1) && c!='\n' && i < 80) r[i++] = c;
r[i] = 0;
tcsetattr(0,TCSANOW,&old);
printf("Entered <%s>\n",r);
return 0;
}
#include<stdio.h>
...
int count=0;
char buffer[81];
int ch=getchar();
while(count<80&&ch!='\n'&&ch!='\r'&&ch!=EOF){
buffer[count]=ch;
count=count+1;
ch=getchar();
}
buffer[count]='\0';
Once you have buffer as a string, make sure you digest the rest of the line of input to get the input stream ready for its next use.
This can be done by the following code (taken from the scanf section of this document):
scanf("%*[^\n]"); /* Skip to the End of the Line */
scanf("%*1[\n]"); /* Skip One Newline */
#include <stdio>
...
char buf[80];
int i;
for (i = 0; i < sizeof(buf) - 1; i++)
{
int c = getchar();
if ( (c == '\n') || (c == EOF) )
{
buf[i] = '\0';
break;
}
buf[i] = c;
}
buf[sizeof(buf] - 1] = '\0';