I m trying to understand how to return a string in c. I tried different ways but didnt manage to do it. Could you edit this code?
char dublicate(char str[])
{
return str[20];
}
int main()
{
char str[20];
scanf("%s", &str);
printf("%s", dublicate(str));
return 0;
}
You can do something like this. string_dupe creates a copy of the string sent from scanf, which must use malloc() or strdup() to allocate space for it on the heap. The pointer to the first element in duplicate is then returned to main and printed out. Then free() is executed to release the memory allocated for the string on the heap.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 20
char *string_dupe(char *string);
int
main(void) {
char str[SIZE];
char *strcopy = NULL;
printf("Enter string: ");
scanf("%s", str);
strcopy = string_dupe(str);
printf("\nYour copied string: %s", strcopy);
free(strcopy);
return 0;
}
char
*string_dupe(char *string) {
char *duplicate = NULL;
if ((duplicate = malloc(strlen(string)+1)) == NULL) {
fprintf(stderr, "Memory not allocated\n");
exit(EXIT_FAILURE);
}
strcpy(duplicate, string);
return duplicate;
}
Change the return type of dublicate, and change how you read into str in your call to scanf:
char *dublicate(char str[])
{
return str;
}
int main() {
char str[20];
scanf("%s", str);
printf("%s", dublicate(str));
return 0;
}
A string is essentially a pointer to a character that is the first character of the string. (The end of the string is determined by the '\0' character.) So all you have to return is a char pointer.
Related
I have a function like so
char *string(FILE *ifp)
{
char string[256];
fscanf(ifp, "%s", string);
return string;
}
int main()
{
.......
printf("%s", string(ifp));
}
and it prints NULL, any fixes? Thanks
You are returning a local address, which you should have caught by looking at the warning.
In function ‘string’:
warning: function returns address of local variable [-Wreturn-local-addr]
return string;
^~~~~~
You have two choices:
Pass a pointer to the char array to your function (string) or
Malloc the return string (string_from_file)
#include <stdio.h>
#include <string.h> // for memset
char *string(FILE *ifp, char s[256])
{
fscanf(ifp, "%255s", s);
}
char *string_from_file(FILE *ifp)
{
char *s = malloc(256);
fscanf(ifp, "%255s", s);
return s;
}
int main(int ac, char **av)
{
FILE *ifp = fopen(av[1], "r");
// using ptr:
char s[256];
memset(s, 0, 256); // fill s with '\0'
string(ifp, s);
printf("%s\n", s);
// using malloc:
printf("%s\n", string_from_file(ifp));
}
Note that it will only get you the first few words of your program, let me know if it was helpful
NB: I did not rewind the file pointer, so the above example will print first two words.
Your "char string[]" is a local variable create in your string function, but in C local variable are not stilling availlable after the function was executed (the memory used for this variable is free to be available for an other program);
You can keep the memory for you program with malloc function, but attention never forget to free malloced memory !!
#include <stdlib.h>
char *get_file_content(FILE *ifp)
{
char *string = malloc(sizeof(char) * 256);
if (string == NULL)
return NULL; //don't continue if the malloc failed
fscanf(ifp, "%s", string);
return string;
}
int main(void)
{
...
free(string); //free memory you malloced
return 0;
}
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;
}
So I'm supposed to write a program that removes every occurence of substring p from string s, and then print it, using a recursive function, and I'm all out of ideas, so if anyone knows how, let me know. This is as far as I've got:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
void remove(char *s, char *p)
{
char *c=strstr(s,p);
if(c == 0)
return;
}
int main()
{
char s[100], p[50];
printf("Enter string and substring: ");
scanf("%s %s", s, p);
remove(s, p);
printf("New string: %s", s);
getchar();
getchar();
return 0;
}
This should work:
#include <stdio.h>
#include <string.h>
void removestr(char *s, char *p, int len)
{
char *c=strstr(s,p); // strstr returns the address where the substring starts
if(c) {
strcpy(c,c+len); //if the substring was found, copy over it the
//string starting from where the substring ends e.g. (assume
//p="the") thisthestring => thisstring
removestr(s,p,len); //call the function again
}
else
return; //stop if no substring was found
}
int main(void)
{
char s[100], p[50];
printf("Enter string and substring: ");
if(scanf("%99s",s)==1 && scanf("%49s",p)==1) //it's important to check the input
// also %s is vulnerable to overflow, specify the sizes to be safe
removestr(s, p , strlen(p));
printf("New string: %s", s);
getchar();
getchar();
return 0;
}
I have a struct defined as;
struct player {
int no, age;
char name[20];
} players[10];
Array is filled from file. What I try to do is, take input from user, add input to char array, send it to search(char lookup[]) function and strstr name field in a loop.
EDİT: Sorry I corrected the order. I'm trying to strstr in a loop.
char *p = strstr(players[x].name, inputFromUser);
but p is always null. How can I do this?
Thanks in advance.
EDIT - Code Added...
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
struct player {
int no, age;
char name[20];
} players[20];
void fillstruct(char *);
void search(char []);
int main(int argc, char *argv[])
{
int arg;
int c;
int d;
int i=0;
char a[100];
char *filename = NULL;
while((arg=getopt(argc, argv, "f:"))!=-1)
{
switch(arg)
{
case 'f':
filename = optarg;
fillstruct(filename);
break;
default:
break;
}
}
while((c=fgetc(stdin))!=EOF)
{
if(c!=10)
{
a[i]=c;
i++;
}
else
{
a[i]='\0';
search(a);
i=0;
}
}
return 0;
}
void search(char a[])
{
int i=0;
int col;
int found=0;
char *p =NULL;
while((i<20)&&(found==0))
{
p = strstr(a, players[i].name);
if(p)
{
col = p-a;
printf("\nPlayer '%s' found in '%s'.. Found index: %d", a, players[i].name, col);
found=1;
}
else
{
printf("\np=%s a=%s player[%d].name=%s", p, a, i, players[i].name);
}
i++;
}
}
void fillstruct(char *name)
{
FILE *fp;
char line[100];
int i=0;
fp = fopen(name, "r");
if(fp==NULL)
{
exit(1);
}
while(fgets(line, 100, fp)!=NULL)
{
players[i].no=i;
strcpy(players[i].name, line);
fprintf(stdout, "\nplayer=%s", players[i].name);
players[i].age=20;
i++;
}
fclose(fp);
}
Added as answer as suggested by mic_e
Assuming you're trying to search for a player name using the input from a user, you have the arguments of strstr in the reverse order. Also note that strstr is case sensitive.
char *p = strstr(players[x].name, inputFromUser);
fgets stores the \n and then stops taking input.
So suppose a player name is "user", players[i].name will be equal to "user\n" while a is "user".
So return of strstr is always NULL.
Try this instead:
p = strstr(players[i].name,a);
OR, remove the \n after taking input from file by fgets:
while(fgets(line, 100, fp)!=NULL)
{
players[i].no=i;
strcpy(players[i].name, line);
players[i].name[strlen(players[i].name)-1]='\0'; //add this line
fprintf(stdout, "\nplayer=%s", players[i].name);
players[i].age=20;
i++;
}
Like this:
char *p = strstr(players[x].name, inputFromUser);
It should work, It's fail if your input is wrong let me expalain in simple
int main()
{
char *ret;
char mystr[]="stack";
char str[]="This is stack over flow string";
ret = strstr(str, mystr);
printf("The substring is: %s\n", ret);
return(0);
}
Output is
The substring is: stack over flow string
That means
This function returns a pointer to the first occurrence in str of any of the entire sequence of characters specified in mystr, or a null pointer if the sequence is not present in str.
It case sensitive function means if try to search like
char mystr[]="Stack";//Note here first char is capital
And you got output like
The substring is: (null)
You can check your input and target string at your side by just printing content of it and verify it's correct or not.
printf("str1:%s str2:%s\n",players[x].name,inputFromUser)
char *p = strstr(players[x].name, inputFromUser);
I hope this clear your doubts.
That Should Work.
I think You have the problem with file reading Which fills the data array.
Please make sure that data you filled into structure is Ok.
And strstr returns address of the first Occurrence of the string1 in string2
where,
strstr(string2, string1);
How do I add two strings?
I tried name = "derp" + "herp";, but I got an error:
Expression must have integral or enum type
C does not have the support for strings that some other languages have. A string in C is just a pointer to an array of char that is terminated by the first null character. There is no string concatenation operator in C.
Use strcat to concatenate two strings. You could use the following function to do it:
#include <stdlib.h>
#include <string.h>
char* concat(const char *s1, const char *s2)
{
char *result = malloc(strlen(s1) + strlen(s2) + 1); // +1 for the null-terminator
// in real code you would check for errors in malloc here
strcpy(result, s1);
strcat(result, s2);
return result;
}
This is not the fastest way to do this, but you shouldn't be worrying about that now. Note that the function returns a block of heap allocated memory to the caller and passes on ownership of that memory. It is the responsibility of the caller to free the memory when it is no longer needed.
Call the function like this:
char* s = concat("derp", "herp");
// do things with s
free(s); // deallocate the string
If you did happen to be bothered by performance then you would want to avoid repeatedly scanning the input buffers looking for the null-terminator.
char* concat(const char *s1, const char *s2)
{
const size_t len1 = strlen(s1);
const size_t len2 = strlen(s2);
char *result = malloc(len1 + len2 + 1); // +1 for the null-terminator
// in real code you would check for errors in malloc here
memcpy(result, s1, len1);
memcpy(result + len1, s2, len2 + 1); // +1 to copy the null-terminator
return result;
}
If you are planning to do a lot of work with strings then you may be better off using a different language that has first class support for strings.
#include <stdio.h>
int main(){
char name[] = "derp" "herp";
printf("\"%s\"\n", name);//"derpherp"
return 0;
}
David Heffernan explained the issue in his answer, and I wrote the improved code. See below.
A generic function
We can write a useful variadic function to concatenate any number of strings:
#include <stdlib.h> // calloc
#include <stdarg.h> // va_*
#include <string.h> // strlen, strcpy
char* concat(int count, ...)
{
va_list ap;
int i;
// Find required length to store merged string
int len = 1; // room for NULL
va_start(ap, count);
for(i=0 ; i<count ; i++)
len += strlen(va_arg(ap, char*));
va_end(ap);
// Allocate memory to concat strings
char *merged = calloc(sizeof(char),len);
int null_pos = 0;
// Actually concatenate strings
va_start(ap, count);
for(i=0 ; i<count ; i++)
{
char *s = va_arg(ap, char*);
strcpy(merged+null_pos, s);
null_pos += strlen(s);
}
va_end(ap);
return merged;
}
Usage
#include <stdio.h> // printf
void println(char *line)
{
printf("%s\n", line);
}
int main(int argc, char* argv[])
{
char *str;
str = concat(0); println(str); free(str);
str = concat(1,"a"); println(str); free(str);
str = concat(2,"a","b"); println(str); free(str);
str = concat(3,"a","b","c"); println(str); free(str);
return 0;
}
Output:
// Empty line
a
ab
abc
Clean-up
Note that you should free up the allocated memory when it becomes unneeded to avoid memory leaks:
char *str = concat(2,"a","b");
println(str);
free(str);
I'll assume you need it for one-off things. I'll assume you're a PC developer.
Use the Stack, Luke. Use it everywhere. Don't use malloc / free for small allocations, ever.
#include <string.h>
#include <stdio.h>
#define STR_SIZE 10000
int main()
{
char s1[] = "oppa";
char s2[] = "gangnam";
char s3[] = "style";
{
char result[STR_SIZE] = {0};
snprintf(result, sizeof(result), "%s %s %s", s1, s2, s3);
printf("%s\n", result);
}
}
If 10 KB per string won't be enough, add a zero to the size and don't bother, - they'll release their stack memory at the end of the scopes anyway.
You should use strcat, or better, strncat. Google it (the keyword is "concatenating").
You cannot add string literals like that in C. You have to create a buffer of size of string literal one + string literal two + a byte for null termination character and copy the corresponding literals to that buffer and also make sure that it is null terminated. Or you can use library functions like strcat.
Concatenate Strings
Concatenating any two strings in C can be done in atleast 3 ways :-
1) By copying string 2 to the end of string 1
#include <stdio.h>
#include <string.h>
#define MAX 100
int main()
{
char str1[MAX],str2[MAX];
int i,j=0;
printf("Input string 1: ");
gets(str1);
printf("\nInput string 2: ");
gets(str2);
for(i=strlen(str1);str2[j]!='\0';i++) //Copying string 2 to the end of string 1
{
str1[i]=str2[j];
j++;
}
str1[i]='\0';
printf("\nConcatenated string: ");
puts(str1);
return 0;
}
2) By copying string 1 and string 2 to string 3
#include <stdio.h>
#include <string.h>
#define MAX 100
int main()
{
char str1[MAX],str2[MAX],str3[MAX];
int i,j=0,count=0;
printf("Input string 1: ");
gets(str1);
printf("\nInput string 2: ");
gets(str2);
for(i=0;str1[i]!='\0';i++) //Copying string 1 to string 3
{
str3[i]=str1[i];
count++;
}
for(i=count;str2[j]!='\0';i++) //Copying string 2 to the end of string 3
{
str3[i]=str2[j];
j++;
}
str3[i]='\0';
printf("\nConcatenated string : ");
puts(str3);
return 0;
}
3) By using strcat() function
#include <stdio.h>
#include <string.h>
#define MAX 100
int main()
{
char str1[MAX],str2[MAX];
printf("Input string 1: ");
gets(str1);
printf("\nInput string 2: ");
gets(str2);
strcat(str1,str2); //strcat() function
printf("\nConcatenated string : ");
puts(str1);
return 0;
}
Without GNU extension:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
const char str1[] = "First";
const char str2[] = "Second";
char *res;
res = malloc(strlen(str1) + strlen(str2) + 1);
if (!res) {
fprintf(stderr, "malloc() failed: insufficient memory!\n");
return EXIT_FAILURE;
}
strcpy(res, str1);
strcat(res, str2);
printf("Result: '%s'\n", res);
free(res);
return EXIT_SUCCESS;
}
Alternatively with GNU extension:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
const char str1[] = "First";
const char str2[] = "Second";
char *res;
if (-1 == asprintf(&res, "%s%s", str1, str2)) {
fprintf(stderr, "asprintf() failed: insufficient memory!\n");
return EXIT_FAILURE;
}
printf("Result: '%s'\n", res);
free(res);
return EXIT_SUCCESS;
}
See malloc, free and asprintf for more details.
#include <string.h>
#include <stdio.h>
int main()
{
int a,l;
char str[50],str1[50],str3[100];
printf("\nEnter a string: ");
scanf("%s",str);
str3[0]='\0';
printf("\nEnter the string which you want to concat with string one: ");
scanf("%s",str1);
strcat(str3,str);
strcat(str3,str1);
printf("\nThe string is %s\n",str3);
}
using memcpy
char *str1="hello";
char *str2=" world";
char *str3;
str3=(char *) malloc (11 *sizeof(char));
memcpy(str3,str1,5);
memcpy(str3+strlen(str1),str2,6);
printf("%s + %s = %s",str1,str2,str3);
free(str3);
my here use asprintf
sample code:
char* fileTypeToStr(mode_t mode) {
char * fileStrBuf = NULL;
asprintf(&fileStrBuf, "%s", "");
bool isFifo = (bool)S_ISFIFO(mode);
if (isFifo){
asprintf(&fileStrBuf, "%s %s,", fileStrBuf, "FIFO");
}
...
bool isSocket = (bool)S_ISSOCK(mode);
if (isSocket){
asprintf(&fileStrBuf, "%s %s,", fileStrBuf, "Socket");
}
return fileStrBuf;
}
In C, you don't really have strings, as a generic first-class object. You have to manage them as arrays of characters, which mean that you have to determine how you would like to manage your arrays. One way is to normal variables, e.g. placed on the stack. Another way is to allocate them dynamically using malloc.
Once you have that sorted, you can copy the content of one array to another, to concatenate two strings using strcpy or strcat.
Having said that, C do have the concept of "string literals", which are strings known at compile time. When used, they will be a character array placed in read-only memory. It is, however, possible to concatenate two string literals by writing them next to each other, as in "foo" "bar", which will create the string literal "foobar".