So I am writing this code to print string length of any string I input and I basically have the code already working but I am having trouble because when I enter a blank string my program doesn't print to screen correctly. It works with a space(spacebar) and all other strings but I must be able to enter an empty string. we are supposed to use something like:
buf[strlen(buf) - 1] = '\0';
to enter and print empty strings,
but I am not sure how to enter it in the code correctly. Any ideas??
here is my program:
#include<stdio.h>
#include<conio.h>
#include<string.h>
int *MyStrlen(const char *string2);
int main()
{
char string2[100];
printf("Enter a string: \n");
scanf("%100[^\n]",&string2);
int length, length2;
length = strlen(string2);
length2 = MyStrlen(string2);
printf("strlen(''%s'') returned %d\n", &string2, length);
printf("MyStrlen(''%s'') returned %d\n", &string2, length2);
return 0;
}
also, here is MyStrlen function, All works correctly besides entering empty string.
int *MyStrlen(const char *string2)
{
int stringcount=0;
while (string2[stringcount]!='\0')
{
stringcount++;
}
return stringcount;
}
Maybe the problem could be corrected with:
Initilize the first element of string2 to '\0' before the scanf:
string2[0] = '\0';
Change the return type of int *MyStrlen(...) to int:
int MyStrlen(const char *string2);
As this post: How to input a string using scanf in c including whitespaces,
a safer way is to specify a size 1 less than the size of string2 buffer:
scanf("%99[^\r\n]", &string2[0]);
Check out the scanf man page for more information.
The code:
#include<stdio.h>
#include<conio.h>
#include<string.h>
int MyStrlen(const char *string2);
// change the return type to int
int MyStrlen(const char *string2)
{
int stringcount=0;
while (string2[stringcount] != '\0')
stringcount++;
return stringcount;
}
int main()
{
char string2[100];
// Initialize the first element to 0
string2[0] = '\0';
printf("Enter a string: \n");
scanf("%99[^\r\n]", &string2[0]);
int length, length2;
length = strlen(string2);
length2 = MyStrlen(string2);
// Change to &string2 to string2
printf("strlen(''%s'') returned %d\n", string2, length);
printf("MyStrlen(''%s'') returned %d\n", string2, length2);
return 0;
}
The output with empty string:
Enter a string:
strlen('''') returned 0
MyStrlen('''') returned 0
The output with "aaa":
Enter a string:
aaa
strlen(''aaa'') returned 3
MyStrlen(''aaa'') returned 3
Well, the problem is with
scanf("%100[^\n]",&string2);
Change it to
fgets (string2, 100, stdin);
Because that scanf cannot read a blank string.
Also, as mentioned in #M.M's comment, check for '\n':
int last = strlen (string2) -1;
if (string2 [last] = '\n') {
string2 [last] = '\0';
}
In the second case I entered a blank string.
The completely corrected code:
#include<stdio.h>
#include<conio.h>
#include<string.h>
int *MyStrlen(const char *string2);
// change the rerturn type to int
int *MyStrlen(const char *string2)
{
int stringcount=0;
while (string2[stringcount] != '\0')
stringcount++;
return stringcount;
}
int main()
{
char string2[100];
// Initialize the first element to 0
string2[0] = '\0';
printf("Enter a string: \n");
fgets (string2, 100, stdin);
int length, length2;
int last = strlen (string2) -1;
if (string2 [last] = '\n') {
string2 [last] = '\0';
}
length = strlen(string2);
length2 = MyStrlen(string2);
printf("strlen(''%s'') returned %d\n", string2, length);
printf("MyStrlen(''%s'') returned %d\n", string2, length2);
return 0;
}
Also as mentioned in #Gomiero's answer, initialize your string to \0.
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;
}
It shows nothing when you pass the string to the function
int main(void){
char *string[200];
getChar(string);//starts function
printf("This is the string %s",*string);//prints
return 0;
}
Void getChar(char *String[200]){
scanf(" %s",String[200]);//gets string
}
There are multiple problems:
You should use an array of char instead of an array of char *,
you should pass the array directly to scanf():
Void has no capital: void
getChar is confusing to read a string and should be declared or defined before use.
the initial space in scanf(" %s", is redundant: %s already skips initial spaces.
you must tell scanf() the maximum number of characters to store into the destination array, otherwise you will have undefined behavior if the input has too many characters.
Here is a modified version:
#include <stdio.h>
int getword200(char *buf) {
return scanf("%199s", buf);
}
int main() {
char word[200];
if (getword200(word) == 1)
printf("This is the string: %s\n", word);
return 0;
}
The above function assumes the array has a length of at least 200. It would be more general to pass the actual array length and modify the code to handle any length:
#include <limits.h>
#include <stdio.h>
int getword(char *buf, size_t size) {
char format[32];
int length;
if (size == 0)
return NULL;
if (size == 1) {
*buf = '\0';
return buf;
}
if (size > INT_MAX)
length = INT_MAX;
else
length = size - 1;
snprintf(format, sizeof format, "%%%ds", length)
return scanf(format, buf);
}
int main() {
char word[200];
if (getword(word, sizeof word) == 1)
printf("This is the string: %s\n", word);
return 0;
}
I have tried make a program which is fills up a string array with string that is given by the user and after that i run into a problem with the idea that how coud i examine that how many words are in the array. I examined the whitespace characterts but it does not work well, i guess .Because whatever the array contains ,it writes flase value : e.g its contain 2 words when there is only 1 word in it.
int db =0;
char array[255];
void string(char str[]){
printf("Enter a string:");
scanf("%s",str);
}
void words(char str[]){
int i=0;
int len = strlen(str);
while( str[i]!=len)
{
if(str[i]==' ')
db++;
i++;
}
}
int main(int argc,char** argv){
string(array);
words(array);
printf("its contain %d words",db);
}
You have a few problems, but the main is using scanf instead of gets. If you'll run this function you'll see that scanf fails to read beyond whitespace, where gets doesn't: (my input was "123 456 789")
void string(char str[]){
printf("Enter a string:");
scanf("%s",str);
printf("%s\n", str); // the string was scanned until 1st whitespace
gets(str);
printf("%s\n", str); // proper string was read
}
The 2nd thing to note is warnings. The return type of strlen() isn't int, it's size_t (man). Also, you are comparing not matching types (char != int):
void words(char str[]){
int i=0; // change to size_t because it is checked against len
int len = strlen(str); // change to size_t
while( str[i]!=len) // should be i != len because you check the location in the string against the length, not against the char itself!!
{
if(str[i]==' ')
db++;
i++;
}
}
The 3rd thing is logic. What if your string has indeed 2 words: "hello world"? you would only count white_spaces and assume you have only one word. I would add something like:
void words(char str[]){
size_t i=0;
size_t len = strlen(str);
printf("%s\n", str);
while(i!=len)
{
if(str[i]==' ')
db++;
i++;
}
if(i) // if i is positive, there must have been a white_space -> add the 1st word because it wasn't counted (Assuming the string must start with a word and not a white_space!!)
i++;
}
This is how I would rewrite it:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int db =0;
char array[255];
void string(char str[]){
printf("Enter a string:");
gets(str);
}
void words(char str[]){
size_t i = 0;
size_t len = strlen(str);
while(i != len)
{
if(str[i]==' ')
db++;
i++;
}
if(i)
i++;
}
int main(/*no need for argc, argv. You can leave them there, but I prefer to omit if not used*/){
string(array);
words(array);
printf("its contain %d words",db);
return 0;
}
Note that there are still some issues:
What happens if more than one white space is entered between 2 words?
What happens if a white space is the first char (I assumed not, but can it be?)
What happens if the input string is too long?
Analyse main() function
int main(int argc,char** argv){
string(array);
words(array);
printf("its contain %d words",db);
}
when you are calling words(array) function what is array ? nothing. if you are taking array as a global then what's the the needs of passing to function & catching with str .
Next,
void string(char str[]){
printf("Enter a string:");
scanf("%s",str);
}
modify above function as below if you want to scan strings with white spaces.
void string(char str[]){
int len;//define it
fgets(str,len,stdin);//TO READ STRINGS WITH WHITESPACES
}
Next come to your logic, what you want to achieve with while( str[i]!=len) ?
Rotate loop upto NULL & and then modify the condition for finding no of words as below.
void words(char str[]){
int i=0;
// int len = strlen(str);
while( str[i]! = NULL)
{
if(str[i]==' ' && str[i+1] !=' ')
db++;
i++;
}
}
complete program as
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void words(char str[]);
int db =0;
char array[255];
void string(char str[]){
int n;// define it
printf("Enter a string:");
fgets(str,n,stdin);// now data is there in str not in array variable thats why call words() function from here only it's a better option
words(str);// call from here bcz now you have str
}
void words(char str[]){
int i=0;
printf("string = %s \n",str);
while( str[i] != '\0')
{
if( (str[i]==' ' && str[i+1] !=' ') || str[i+1] == '\0')
db++;
i++;
}
printf("db = %d \n",db);
}
int main(int argc,char** argv){
string(array);
printf("its contain %d words",db);
}
I hope it will helps.
I thought it's the easiest one. You have to start with your counter
int db = 1;
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)
I'm trying to scan user input text for specific words and then, when those words occur, print them to the console.
#import <Foundation/Foundation.h>
#include <stdio.h>
int main(){
char cArray[] = "example";
char cInput[] = "";
char cOutput[] = "";
printf("\nType your message:\n");
for (int y=0; y<1; y++){
fgets(cInput, 120, stdin);
}
printf("\nInitialised character array:\n");
for (int x=0; x<1; x++){
if(strncmp(&cInput[x], &cArray[x], 120) == 0){
strncpy(cOutput, cArray, strnlen(cInput, +1));
printf("%s\n", cOutput);
break;
}
}
}
Output:
Type your message:
example
Initialised character array:
Program ended with exit code: 120
Appreciate any feedback as I'm still learning :)
Thanks.
The edited code:
#include <stdio.h>
#include <string.h>
#define MAX_STR_LEN 120
int main(){
char *cArray[MAX_STR_LEN] = {"example", "this"};
char cInput[MAX_STR_LEN] = "";
char cOutput[MAX_STR_LEN] = "";
printf("Type your message:\n");
for (int y=0; y<1; y++){
fgets(cInput, MAX_STR_LEN, stdin);
char * ptr = cInput;
while((ptr=strstr(ptr, *cArray)) != NULL){
strncpy(cOutput, ptr, strlen(*cArray));
printf("Initialised string array:\n%s\n", cOutput);
ptr++;
}
}
}
Works although I'm encountering a different problem now. The output only seems to register one word before it completes, thus only "example" is printed.
Output:
Type your message:
this is an example
Initialised string array:
example
Program ended with exit code: 0
char cInput[] = "";
The sizeof this array is 1.
fgets(cInput, 120, stdin);
This is array out of bound write which will lead to undefined behavior.
Have
char cInput[120] = "";
You need to take care of
char cOutput[120] = "";
also. Since you are trying to write to this array after comparing.
You need strstr function from string.h
const char * strstr ( const char * str1, const char * str2 );
the following gives you an example of usage:
#include <stdio.h>
#include <string.h>
#define MAX_STR_LEN 120
int main(){
char cArray[MAX_STR_LEN] = "example"; // string to be searched in the input string
char cInput[MAX_STR_LEN] = ""; // input string
char cOutput[MAX_STR_LEN] = ""; // buffer for found string
printf("\nType your message:\n");
for (int y=0; y<1; y++){ // this loop from original example looks strange, but it works
fgets(cInput, MAX_STR_LEN, stdin);
}
// search in the input string
char * ptr;
if( ( ptr=strstr(cInput, cArray) ) != NULL)
{
//copy the string to cOutput
strncpy(cOutput, ptr, strlen(cArray));
// output the found string
printf("String that was found: \n%s\n", cOutput);
}
else
{
printf("String was not found in the input!\n");
}
}
EDIT:
If you want to all the strings, use the following loop instead of if-else:
// search in the input string
char * ptr = cInput;
while( ( ptr=strstr(ptr, cArray) ) != NULL)
{
//copy the string to cOutput
strncpy(cOutput, ptr, strlen(cArray));
// output the found string
printf("String \"%s\" was found at position %d\n", cOutput, (int)(ptr - cInput + 1));
// find next string
ptr++;
}