I have strange problem where the output of the concatenation comes with a new line between each string input. I tried couple of different things eg. removing the dynamic memory allocation, copying strings into one another and then concatenating. the same issue is there. any ideas why?
Input:
> one
> two
Output:
> Result of concatenation: one
> two
here is the code
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
/* code */
char string1[100];
char string2[100];
char *concat;
fgets(string1,100,stdin);
fgets(string2,100,stdin);
unsigned int size = strlen(string1) + strlen(string2);
concat = (char *) malloc(sizeof(char) * size);
if (concat==NULL)
{
exit(0);
}
strcat(concat,string1);
strcat(concat,string2);
printf("Result of concatenation: %s",concat);
return 0;
}
For starters the function fgets can append the new line character to the entered strings. You should remove it. For example
fgets(string1,100,stdin);
string1[ strcspn( string1, "\n" ) ] = '\0';
fgets(string2,100,stdin);
string2[ strcspn( string2, "\n" ) ] = '\0';
Secondly you forgot about the terminating zero when was allocating memory. Instead of
unsigned int size = strlen(string1) + strlen(string2);
You have to write
size_t size = strlen(string1) + strlen(string2) + 1;
Futhermore the allocated memory is not initislaized. You have to write
concat[0] = '\0';
before these statements
strcat(concat,string1);
strcat(concat,string2);
And do not forget to free the allocated memory.
free( concat );
From the man page:
char *fgets(char *restrict s, int n, FILE *restrict stream);
...
The fgets() function shall read bytes from stream into the array
pointed to by s, until nā1 bytes are read, or a <newline> is read
and transferred to s, or an end-of-file condition is encountered.
The string is then terminated with a null byte.
You are likely including the \n (new line characters) read by fgets in your concatenated array of characters.
Related
Let's say I have the following string stored in char *m;
char *m = "K: someword\r\n";
The m will be inputed by the user so the user will write in the console:
K: someword\r\n
The someword can have different length, while K: \r\n will always be the same.
Now my question is, which is the best way after I read this input to extract someword from it and save it into a new char* variable?
Use sscanf() like this:
#include <stdio.h>
int main (void)
{
char buffer [50], k, return_car, new_line;
int n = sscanf ("K: someword\r\n", "%c: %s%c%c", &k, buffer, &return_car, &new_line);
printf ("The word is \"%s\". sscanf() read %d items.\n", buffer, n);
return 0;
}
Output:
The word is "someword". sscanf() read 4 items
Since both the substrings we aren't interested in ("K: " and "\r\n") are of fixed length, you can do this:
char *s;
size_t len = strlen(m);
s = malloc(len);
strcpy(s, m + 3);
s[len - 4] = 0;
printf("%s\n", s);
free(s);
Note that I declared a new char * variable to copy to since m is in read-only memory, and that robust code would handle the case where malloc failed and returned NULL.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
char *m = "K: someword\r\n";
const size_t someword_len = strlen(&m[3]);
char *someword = malloc(someword_len);
if (someword == NULL) { fprintf(stderr, "Malloc error\n"); abort(); }
memcpy(someword, &m[3], someword_len - 2);
someword[someword_len - 1] = '\0';
puts(someword);
free(someword);
}
You assume that string m always starts with "K: " (that's 3 characters) and ends with "\r\n" (that's two characters).
I believe strlen(m) will be faster then strchr(m, '\r') or strrchr(m, '\r') on most platforms
After you have the length of the string, using memcpy instead of strcpy will be faster.
Remember to null terminate your string
Remember to handle errors.
char input[1000];
I want to copy input into a dynamically allocated character array, how do I approach this problem.
So far I have used strncpy, but get lots of errors.
Are you looking for something like this:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main() {
int i;
char input[1000] = "Sample string";
char *in = malloc(1000 * sizeof(char)); // use dynamic number instead of 1000
strcpy(in, input);
for (i = 0; i < 5; ++i) { // intentionally printing the first 5 character
printf("%c", in[i]);
}
}
The output is:
Sampl
Edit: In C++ the cast is required for malloc, so I write:
(char *)malloc(1000 * sizeof(char))
But in C, never cast the result of malloc().
What you can do is just use strcpy() offer by C string.h after dynamically allocating memory to your array, as shown:
char *input = malloc(1000*sizeof(char));
and if the string you are trying to copy to variable input exceeds the allocated memory size (strlen > 999: don't forget! String has a null terminator '\0' that takes up the additional 1 char space), just realloc as shown:
input = realloc(input, 1000*2*sizeof(char));
/* check if realloc works */
if (!input) {
printf("Unexpected null pointer when realloc.\n");
exit(EXIT_FAILURE);
}
The condition is:
I want to input a line from standard input, and I don't know the size of it, maybe very long.
method like scanf, getsneed to know the max length you may input, so that your input size is less than your buffer size.
So Is there any good ways to handle it?
Answer must be only in C, not C++, so c++ string is not what I want. I want is C standard string, something like char* and end with '\0'.
The C standard doesn't define such a function, but POSIX does.
The getline function, documented here (or by typing man getline if you're on a UNIX-like system) does what you're asking for.
It may not be available on non-POSIX systems (such as MS Windows).
A small program that demonstrates its usage:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char *line = NULL;
size_t n = 0;
ssize_t result = getline(&line, &n, stdin);
printf("result = %zd, n = %zu, line = \"%s\"\n", result, n, line);
free(line);
}
As with fgets, the '\n' newline character is left in the array.
One way is to run a loop with getchar and keep placing the characters into an array. Once the array is full, reallocate it to a larger size.
There is an often overlooked conversion specification within scanf that will allocate memory sufficient to hold the string input regardless of length. Newer versions of scanf use m for this purpose. Older versions used a. For example:
#include <stdio.h>
#include <stdlib.h>
int main (void) {
char *str = NULL;
printf (" enter a string of any length, whitespace is OK: ");
scanf ("%m[^\n]%*c", &str);
printf ("\n str: %s\n\n", str);
if (str) free (str);
return 0;
}
Note: scanf requires a char ** pointer argument to receive the allocated string. Also note scanf does not include the '\n' in the stored string. Further note the %*c which receives and discards the '\n' character to prevent the newline from remaining in the input buffer. You may also precede the conversion specifier with whitespace to skip any/all whitepace that may exist in the input buffer.
Lastly Note: there are reports that not all implementations of scanf offer this feature. (which may also be confusion of the m/a change) Check your implementation.
One of the method is using getchar() function we can get input in a character and transfer it to dynamicall created array. You can see that when it exceeds the default length set by us, we reallocated space for storing character
#include<stdio.h>
#include<stdlib.h>
void main(){
int size = 10;
char* str;
str = (char*) calloc(size,sizeof(char));
char c;
c = getchar();
int t = 0;
int cnt = 0;
int len;
while(c!='\n') {
if(cnt > size) {
str = (char*) realloc(str,2*cnt);
}
str[t] = c;
c = getchar();
t++;
cnt++;
}
str[t]='\0';
printf("The string is %s\n",str);
len = strlen(str);
printf("The size is %d",len);
}
use getchar, malloc and realloc for reading the unlimited input string
Declare String type, you can also use char *
// String type
typedef char *String;
I write this function for joining the char in the end of string
/**
* Join the Char into end of String
*
* #param string - String
* #param c - joined char
*/
void String_joinChar(String *string, const char c)
{
const size_t length = strlen(*string);
(*string) = (String)realloc((*string), sizeof(char) * (length + 2));
(*string)[length] = c;
(*string)[length + 1] = '\0';
}
This function for inputting string, which read the char from keyboard by using getchar and join it in the end of current string.
/**
* Input String
*
* #return Inputed String
*/
String String_input()
{
String string = (String)malloc(sizeof(char));
strcpy(string, "");
char cursor;
fflush(stdin);
while ((cursor = getchar()) != '\n' && cursor != EOF)
{
String_joinChar(&string, cursor);
}
return string;
}
Cause of using char *, malloc and realloc, we must free it
/**
* Destroy String
*
* #param string - Destroyed String
*/
void String_destroy(String string)
{
free(string);
}
And now we just use it !!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
String string = String_input();
printf("\n%s\n", string);
String_destroy(string);
return 0;
}
Hope useful to you!
Ok, so I'm a person who usually writes Java/C++, and I've just started getting into writing C. I'm currently writing a lexical analyser, and I can't stand how strings work in C, since I can't perform string arithmetic. So here's my question:
char* buffer = "";
char* line = "hello, world";
int i;
for (i = 0; i < strlen(line); i++) {
buffer += line[i];
}
How can I do that in C? Since the code above isn't valid C, how can I do something like that?
Basically I'm looping though a string line, and I'm trying to append each character to the buffer string.
string literals are immutable in C. Modifying one causes Undefined Behavior.
If you use a char array (your buffer) big enough to hold your characters, you can still modify its content :
#include <stdio.h>
int main(void) {
char * line = "hello, world";
char buffer[32]; // ok, this array is big enough for our operation
int i;
for (i = 0; i < strlen(line) + 1; i++)
{
buffer[i] = line[i];
}
printf("buffer : %s", buffer);
return 0;
}
First off the buffer needs to have or exceed the length of the data being copied to it.
char a[length], b[] = "string";
Then the characters are copied to the buffer.
int i = 0;
while (i < length && b[i] != '\0') { a[i] = b[i]; i++; }
a[i] = '\0';
You can reverse the order if you need to, just start i at the smallest length value among the two strings, and decrement the value instead of increment. You can also use the heap, as others have suggested, ordinate towards an arbitrary or changing value of length. Furthermore, you can change up the snippet with pointers (and to give you a better idea of what is happening):
int i = 0;
char *j = a, *k = b;
while (j - a < length && *k) { *(j++) = *(k++); }
*j = '\0';
Make sure to look up memcpy; and don't forget null terminators (oops).
#include <string.h>
//...
char *line = "hello, world";
char *buffer = ( char * ) malloc( strlen( line ) + 1 );
strcpy( buffer, line );
Though in C string literals have types of non-const arrays it is better to declare pointers initialized by string literals with qualifier const:
const char *line = "hello, world";
String literals in C/C++ are immutable.
If you want to append characters then the code can look the following way (each character of line is appended to buffer in a loop)
#include <string.h>
//...
char *line = "hello, world";
char *buffer = ( char * ) malloc( strlen( line ) + 1 );
buffer[0] = '\0';
char *p = Buffer;
for ( size_t i = 0; i < strlen( line ); i++ )
{
*p++ = line[i];
*p = '\0';
}
The general approach is that you find the pointer to the terminating zero substitute it for the target character advance the pointer and appenf the new terminating zero. The source buffer shall be large enough to accomodate one more character.
If you want to append a single character to a string allocated on the heap, here's one way to do it:
size_t length = strlen(buffer);
char *newbuffer = realloc(buffer, length + 2);
if (newbuffer) { // realloc succeeded
buffer = newbuffer;
buffer[length] = newcharacter;
buffer[length + 1] = '\0';
}
else { // realloc failed
// TODO handle error...
free(buffer); // for example
}
However, this is inefficient to do repeatedly in a loop, because you'll be repeatedly calling strlen() on (essentially) the same string, and reallocating the buffer to fit one more character each time.
If you want to be smarter about your reallocations, keep track of the buffer's current allocated capacity separately from the length of the string within it ā if you know C++, think of the difference between a std::string object's "size" and its "capacity" ā and when it's necessary to reallocate, multiply the buffer's size by a scaling factor (e.g. double it) instead of adding 1, so that the number of reallocations is O(log n) instead of O(n).
This is the sort of thing that a good string class would do in C++. In C, you'll probably want to move this buffer-management stuff into its own module.
The simplest solution, lacking any context, is to do:
char buffer[ strlen(line) + 1 ];
strcpy(buffer, line);
You may be used to using pointers for everything in Java (since non-primitive types in Java are actually more like shared pointers than anything else). However you don't necessarily have to do this in C and it can be a pain if you do.
Maybe a good idea given your background would be to use a counted string object in C, where the string object owns its data. Write struct my_string { char *data; size_t length; } . Write functions for creating, destroying, duplicating, and any other operation you need such as appending a character, or checking the length. (Separate interface from implementation!) A useful addition to this would be to make it allocate 1 more byte than length, so that you can have a function which null-terminates and allows it to be passed to a function that expects a read-only C-style string.
The only real pitfall here is to remember to call a function when you are doing a copy operation, instead of allowing structure assignment to happen. (You can use structure assignment for a move operation of course!)
The asprintf function is very useful for building strings, and is available on GNU-based systems (Linux), or most *BSD based systems. You can do things like:
char *buffer;
if (asprintf(&buffer, "%s: adding some stuff %d - %s", str1, number, str2) < 0) {
fprintf(stderr, "Oops -- out of memory\n");
exit(1); }
printf("created the string \"%s\"\n", buffer);
free(buffer); /* done with it */
Appending is best done with snprintf
Include the stdio.h header
#include <stdio.h>
then
char* buffer;
char line[] = "hello, world";
// Initialise the pointer to an empty string
snprintf(buffer, 1, "%s", "");
for (i = 0; i < strlen(line); ++i) {
snprintf(buffer, sizeof line[i], "%s%s", buffer, line[i]);
}
As you have started the code you have there is different from the question you are asking.
You could have split the line with strtok though.
But I hope my answer clarifies it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * odd(const char * S, char * dest);
int main()
{
char * source = "abcdefghijklmnopacegiacegi";
unsigned int length = strlen(source);
char dest[length];
printf("%s\n",odd(source, dest));
}
char * odd(const char * source, char * dest)
{
int count = 0;
unsigned int length = strlen(source);
for(int i = 0; i < length; i++)
{
if( (source[i] %2 )!= 0)
{
dest[count] = source[i];
count++;
}
}
return dest;
}
the size of dest increases and produces garbage for any values after the length of source
You have to manually include the ending \0 to the string, that is, at the end of add, you have to add:
dest[count] = '\0';
You know, the length of strings in C is accounted searching for the \0 character. You have to include one of those at the end of each C string. If not, the string may contain any garbage till the first \0 that will be printed.
Finally, when creating dest, you have also to increase the length of the reserved space in one to accomodate that ending 0 character. The strlen does not count that ending 0 character.
Your odd function forgets to NUL-terminate dest, so printf continues to read happily past the intended end of the string, outputting the garbage that happens to be on the stack.
Also, dest must be one character longer, since strlen tells the length of the string not including the closing NUL, thus, if source is by chance all of odd characters, you have a (small) buffer overflow.
You don't copy the terminating \0.