Search my name in statement ! in c program using string functions - c

I need to know whats wrong with this code.
#include<stdio.h>
#include<string.h>
int main() {
char a[50], b[100], c[5000];
char *ret;
//enter first name
gets(a);
//enter secend name
gets(b);
//enter statement
gets(c);
strcat(a,b);
if(strstr(c,a) != NULL) {
printf("found your full name");
} else {
printf("not found your full name");
}
return 0;
}
It does not work when, I use the following lines:
mohamed
ramadan
abdelrhmanamirelbatanonywoofymohamedramadanahmedalyomarelazazyahmedkamelahmedsa‌​lemessamelnaggarkhaledhelmy
It should find something, but the programm tells me, that it hasn't.

Point 1
As per the man page of strcat()
char *strcat(char *dest, const char *src);
If dest is not large enough, program behavior is unpredictable
In your case,
strcat(a,b);
a maybe not having enough memory to hold the concatenated string. Possible UB. Change the logic.
Point 2
gets() suffers from buffer overflow issue. Use fgets() instead.

Related

String comparison in c

#include<stdio.h>
#include<string.h>
int main()
{
char strg1[];
char strg2[] = "football"
printf("Enter first string: ");
gets(strg1);
if(strcmp(strg1, strg2)==0)
{
printf("\nEqual");
}
else
{
printf("\nNot Equal");
}
return 0;
}
I'm getting a string from the user as input and I want to compare it with a ready-made string I have, whether it's equal or not. When I try with strcmp, they are not equal. When I try with strncmp, for example, user footballABC wrote my string football is still equal because with strncmp it is 8 characters. I've limited it. Is there a solution?
You've done following mistakes in your program:
Not allocated space for char strg1[];(It will throw error while compiling).
error: definition of variable with array type needs an explicit size or an initializer
char strg1[];
Used gets() for reading string which can lead to Buffer Overflow.
while using gets() you should have been warned by compiler.
warning: this program uses gets(), which is unsafe.
Full article why gets() in not safe.
Corrected program:
#include<stdio.h>
#include<string.h>
int main()
{
// char strg1[]; // Error!
char strg1[100]; // Allocate space to Array.
char strg2[] = "football";
printf("Enter first string: ");
scanf("%s",strg1); // Use Scanf() instead of gets().
if(strcmp(strg1, strg2)==0)
{
printf("\nEqual");
}
else
{
printf("\nNot Equal");
}
return 0;
}

fgets() function doesn't work

I want to calculate length of string and copy the string to another without using c library function, but when I use fgets() function to read the string from keyboard, the code not showing the actual value of length as well as the destination string. I use the fgets() function instead of gets() because the compiler says that gets()function is "deprecated".but when I change sizeof(source) in the code to an integer value suppose 50 the code works fine. Can anybody tell me what wrong with this code and why on earth the compiler say that gets() function is deprecated.
This is the code:
#include <stdio.h>
#include <stdlib.h>
int len(char *source);
char *coppy(char *dest,char *source);
int main (void){
char *source,*dest;
source=(char *)malloc(len(source)+1);
printf("enter string:");
fgets(source,sizeof(source),stdin);
if(source[len(source)-1]=='\n'){
source[len(source)-1]='\0';
}
dest=(char *)malloc(len(source)+1);
coppy(dest,source);
printf("dest=%s\n",dest);
printf("length source=%d\n",len(source));
printf("length dest=%d\n",len(dest));
return 0;
}
int len(char *source){
int i=0;
while(*source!='\0'){
source++;
i++;
}
return i;
}
char *coppy(char *dest,char *source){
while(*source!='\0'){
*dest=*source;
source++;
dest++;
}
*dest='\0';
return dest;
}
This is the result when run that code:
enter string:programming
dest=pro
length source=3
length dest=3
Here is your first mistake:
source=(char *)malloc(len(source)+1)
You pass source to the function len before you initialized it, which is undefined behaviour. From hereon in, anything could happen.
The second mistake is your use of fgets:
fgets(source,sizeof(source),stdin);
The second argument to fgets is supposed to be how many characters are available to be written in, not sizeof(source). Read the documentation for fgets, and sizeof if necessary.
Your error is in how you allocate memory for source
source=(char *)malloc(len(source)+1);
What did you expect len(source) to be? Play computer and run through your len function. I'm surprised your code compiles and runs at all. Your len function on an uninitialized char* should be undefined behavior.
That is why your code fails, you are not allocating enough memory to hold your input string.

Implementing strcat using pointers

While doing some programs on strings, I have come across this little problem.
The question which was asked to me was this -
Write a pointer version of the function strcat(s,t) which copies the string t to the end of s.
I wrote the program as this -
#include<stdio.h>
void strcat(char *s, char *t);
int main()
{
char *s1, *s2;
printf("enter the first string\n");
scanf("%s",s1);
printf("Enter the second string\n");
scanf("%s",s2);
strcat(s1,s2);
printf("Strings concatenated\n");
printf("%s",s1);
return 0;
}
void strcat(char *s, char *t)
{
while(*s++)
;
while(*s++ = *t++)
;
}
I know i have done something(or many things) terribly wrong. Because whenever i try to run this code- it gives me segmentation fault. Like this-
Enter the first string
Hello
Enter the second string
Segmentation fault (core dumped)
It would be really helpful if someone points me out the flaw/flaws of my implementation. Thanks in advance.
Thank you very much guys, for such quick responses. But seems that wasn't the only problem. After writing the program like this-
#include<stdio.h>
void strcat(char *s, char *t);
int main()
{
char s1[20], s2[20];
printf("enter the first string\n");
scanf("%s",s1);
printf("Enter the second string\n");
scanf("%s",s2);
strcat(s1,s2);
printf("Strings concatenated\n");
printf("%s",s1);
return 0;
}
void strcat(char *s, char *t)
{
while(*s++)
;
while(*s++ = *t++)
;
}
It runs like this.
Enter the first string
Hello
Enter the second string
There
Hello
It only prints the first string i have entered. Now i think i have made some mistake on that strcat function too.
1) In the main(), you have to allocate memory for both s1 and s2 pointers
char *s1=malloc(100*sizeof(char)), *s2=malloc(100*sizeof(char));
scanf("%99s",s1); //the "%99s" allow to avoid buffer overflow
And if you use gcc and your gcc>2.7 then you can use "%ms" in the scanf() in this way:
scanf("%ms",&s1);
with the "%ms", the scanf() will allocate memory for s1 pointer
2) and you have to add s-- in
while(*s++)
;
s--; // add s-- here
while(*s++ = *t++)
;
because the s pointer is pointing in the next element of '\0' element. the s pointer should be pointed in the '\0' element before starting copy the second string
You don't allocate memory for s1, s1 (or initialized with array), Value of both s1, s1 are garbage .
char *s1, *s2;
printf("enter the first string\n");
scanf("%s",s1);
This causes an undefined behavior.
Suggestion use either:
#define SIZE 1024
char s1[SIZE], s2[SIZE];
or dynamically allocate memory using calloc()/maloc() functions:
char *s1, *s2;
s1 = malloc(SIZE);
s2 = malloc(SIZE);
and lately free() memory explicitly when work done with s1, s2.
Additionally instead of unsafe scanf() use fgets() function to avoid buffer overflow error. read Reading a line using scanf() not good?

strncmp/strcpy corrupting source

today i was trying to get friendly with char * string... but it seems im failing :)
Every time i call strcmp/strncmp/strcpy function my source gets corrupted...
here is the snippet
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct student
{
int UID;
char name[20];
char surname[20];
};
char * getString(int minChars, int maxChars);
struct student * myStud;
int main(int argc, char** argv) {
myStud = (struct student*)malloc(sizeof(struct student));
while(1)
{
printf("\nEnter new name: ");
strcpy(myStud->name,getString(1,19));
printf("\n The values is now %s",myStud->name);
}
return (EXIT_SUCCESS);
}
char * getString(int minChars, int maxChars)
{
char string[maxChars+1];
scanAgain:
scanf("%s",&string);
if(strlen(string)<minChars)
{
printf("\nToo few symbols, try again: ");
goto scanAgain;
}
if(strlen(string)>maxChars)
{
printf("\nToo many symbols, try again: ");
goto scanAgain;
}
string[maxChars]='\0';
return(string);
}
Output:
Enter new name: Alekasdasd
The values is now Alekasda�#
Enter new name:
im just a beginner so it might be something very simple... might be not.
oh and by the way, using linux and netbeans as SDK, gcc as compiler.
You're returning a pointer to a stack variable.
char * getString(int minChars, int maxChars)
{
char string[maxChars+1];
When getString returns, string is invalid. Your return value points to this invalid string.
Use:
char * getString(int minChars, int maxChars, char * string) {
return string;
}
...
char string[100];
getString(1, 2, string);
Also, goto? Stop that please - use for, while do, do while but not goto
char * getString(int minChars, int maxChars)
{
char string[maxChars+1];
...
return(string);
}
The "string" array here is only allocated for the scope of the getString() function. Once it returns (goes out of scope), it ceases to exist and will be overwritten by the rest of your program. The "return(string)" statement returns the pointer of this data that's not allocated anymore -- not the data itself. This happens due to the implicit array-to-pointer conversion in C.
Instead of doing this, your getString() function should take a char* as an argument, which is allocated in the calling function.
I see two problems with your getString() function:
The string variable must be declared static so that the memory used for it is not released (stack, popped) when the function returns.
The parameter to scanf() you do not want the & token, but simply the pointer to the buffer, string.
That is, change the lines:
char string[maxChars+1];
scanf("%s",&string);
to read
static char string[maxChars+1];
scanf("%s",string);
The reason you do not want the ampersand in the scanf() call is the following from the man page, man 3 scanf:
s Matches a sequence of non-white-space characters; the next
pointer must be a **pointer to character array** that is long enough
to hold the input sequence and the terminating null character
('\0'), which is added automatically. The input string stops at
white space or at the maximum field width, whichever occurs
first.
240 lines is not a "snippet".
As James suggested in his comment, reduce the code to the minimum number of lines needed to reproduce the problem. At that stage the cause of the problem should become obvious to you -- if not try posting again.

this code, its work fine and return what i want, but its hangs before print it?

I make this program ::
#include<stdio.h>
char *raw_input(char *msg);
main() {
char *s;
*s = *raw_input("Message Here Is: ");
printf("Return Done..");
printf(s);
}
char *raw_input(char *msg){
char *d;
printf("%s", msg);
scanf("%s",&d);
return d;
}
What this do is, it print my message and scan for input from the user, then print it,, but whats the problem in print the input from the user ???
Update::
I need the raw_input func. call be like this without any extra
*s = *raw_input("Message Here");
I dont want to use this ::
raw_input("Message Here Is: ", d);
....
Just want to return the string that the user will enter .
Update2::
from jamesdlin Answer( Thank You ),,Now its clear to my that's my problem was in how to return an allocated string in this :)
#include<stdio.h>
#define buffer 128
char *raw_input(char *msg);
main() {
char *s;
s = raw_input("Message Here Is: ");
printf("%s\n",s);
}
char *raw_input(char *msg){
char *d;
printf("%s", msg);
fflush(stdout);
fgets(d, buffer, stdin); ## In this there is a problem
return d;
}
now when i start this program its print the message and then just exit(end)the program without taking any word from the user ???
You don't allocate memory for d, so using it in scanf leads to undefined behaviour.
Actually, it's even worse than that: you pass the address of d to scanf, which is then filled with the integer read from console. In effect, you initialize a pointer with an integer value, so the pointer points to somewhere out in the jungle. Thus dereferencing it is undefined behaviour. [Update]: even this is not all: as #Heath pointed out below, this in fact allows you to corrupt your call stack by entering a sufficiently long input on the console :-((( [/Update]
Not to mention that you are trying to return a local variable from your function, which is destroyed as soon as it gets out of scope. This should work better:
void raw_input(char *msg, char *d);
main() {
char d[128];
raw_input("Message Here Is: ", d);
printf("Return Done..");
printf(d);
}
void raw_input(char *msg, char *d){
printf("%s", msg);
scanf("%s", d);
}
Fair enough, this does not prevent buffer overflow... but it is enough to ilustrate my point.
Update: so you want to return an allocated string (i.e. a char* pointer) from raw_input() in any case. AFAIK you have 3 choices:
return a pointer passed in by the caller as a parameter (a slight extension of my example above): this is the one I would prefer. However, this requires an extra function parameter (in fact 2, since we should also pass in the length of the buffer in a proper solution to avoid buffer overflows). So if you absolutely need to stick to the function signature shown above, this isn't an option.
return a pointer to a static / global buffer visible to both caller and callee: this is a variation of the above, to avoid modifying the function signature. The downside is that the code is more difficult to understand and maintain - you don't know that the function modifies a static / global variable without actually looking at its implementation. This in turn also makes unit testing more difficult.
return a pointer to a buffer allocated inside the function - although technically possible, this is the worst option, since you effectively pass on the ownership of the buffer; in other words, the caller must remember to free the buffer returned. In a simple program like the one you showed above, this may not seem like a big issue, but in a big program, that buffer may be passed around to far away places within the app, so there is a high risk that noone frees it in the end, thus leaking memory.
The pointer d in the function is uninitialized. scanf would be filling up arbitrary memory. Instead, you need to pass a buffer (character array) for it to fill, and the buffer has to be defined in main, otherwise it'll be destroyed before you can return it (unless you do dynamic allocation, but that's another story).
#include<stdio.h>
char *raw_input(char *msg);
int main() {
char *s;
s = raw_input("Message Here Is: ");
printf("Return Done..");
printf("%s", s);
free(s);
return 0;
}
char *raw_input(char *msg){
char *d;
d = malloc(20)
if(d==0) return 0;
printf("%s", msg);
scanf("%19s", d);
return d;
}
Try this, should work. The other answers pointed your errors out, as I can see... I was to slow ;)
EDIT: Ok, found an error... fixed it ;)
EDIT2:
Max suggested a struct was possible, here is some code:
#include<stdio.h>
struct mystring{
char str[20];
};
struct mystring raw_input(char *msg);
int main() {
struct mystring input;
input = raw_input("Message Here Is: ");
printf("Return Done..");
printf("%s", input.str);
return 0;
}
struct mystring raw_input(char *msg){
struct mystring input;
printf("%s", msg);
scanf("%19s", input.str);
return input;
}
As mentioned, you aren't allocating memory for use with scanf. But never ever use scanf; it's hard to use correctly and to avoid buffer overflows. Use fgets.
From the comp.lang.c FAQ: Why does everyone say not to use scanf? What should I use instead?
Also, while unrelated to your problem, this bit of code is dangerous:
*s = *raw_input("Message Here Is: ");
printf("Return Done..");
printf(s);
You are passing user-input directly to printf as a format strings, so this is susceptible to format string attacks if the printed string happens to include % characters. Better:
*s = *raw_input("Message Here Is: ");
printf("Return Done..");
printf("%s\n", s);
Also, you might want some newlines when you print. Also:
*s = *raw_input("Message Here Is: ");
won't work because s doesn't point to anything, so you're dereferencing a garbage pointer. Assuming that you fix raw_input to return an allocated string, it should be:
s = raw_input("Message Here Is: ");
Lastly (also unrelated to your problem):
char *raw_input(char *msg){
char *d;
printf("%s", msg);
scanf("%s",&d);
return d;
}
You should call fflush(stdout) after printing the prompt. See My program's prompts and intermediate output don't always show up on the screen, especially when I pipe the output through another program.
Try this experiment:
#include<stdio.h>
char *raw_input(char *msg);
main() {
char *s;
s = raw_input("Message Here Is: ");
printf("Return Done..");
printf(s);
}
char *raw_input(char *msg)
{
int value = 0;
char *d;
printf("%s", msg);
scanf("%s",&d);
if (value)
printf("value has become %08X\n", value);
return d;
}
Perform several experiements with input messages as long as: 3, 4, 5, 7, 8, 9, 11, 12, 13, etc. characters long. See what the result is for the integer variable value. You will see that due to your misuse of scanf() by passing the address of d, you are allowing scanf() to destroy local variables of your function, including the return address.
And that gets us back to the name of this web site.
You can not return a pointer of a variable that has been created inside the function. The variable d is not valid anymore in the main function.
try this:
1. create the variable d in the main function
2. and pass it to the raw_input function
void raw_input(char *msg, char *d)

Resources