I want to get first char character of each string. Here a example:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main() {
int size = 2;
char** text = (char**) malloc(sizeof(char*) * size);
for(int i = 0; i < size; ++i) {
char buf[80];
fgets(buf, 80, stdin);
text[i] = (char*)malloc(strlen(buf));
strcpy(text[i], buf);
}
for(int i = 0; i < strlen(text[i]); ++i) {
printf("%c ", text[i][0]);
}
}
In last for loop, program falls in Segmentation fault. I dont know why.
The strlen function returns the number of characters in the given string not including the terminal nul character; however, the strcpy function copies all characters including that terminating nul!
So, your allocation for text[i] is not quite big enough and, by writing beyond the buffer's bounds, you are getting undefined behaviour.
Add an extra character to the malloc call:
for(int i = 0; i < size; ++i) {
char buf[80];
fgets(buf, 80, stdin);
text[i] = malloc(strlen(buf) + 1); // Need space for the terminal nul!
strcpy(text[i], buf);
}
Or, more simply, use the strdup function, which achieves the same result as your malloc and strcpy in one fell swoop:
for(int i = 0; i < size; ++i) {
char buf[80];
fgets(buf, 80, stdin);
text[i] = strdup(buf);
}
Either way, don't forget to call free on all the buffers you allocate.
EDIT: You are also using the wrong 'limit' in your final output loop; this:
for(int i = 0; i < strlen(text[i]); ++i) { // strlen() is not the # strings
printf("%c ", text[i][0]);
}
Should be:
for(int i = 0; i < size; ++i) { // "size" is your number of strings!
printf("%c ", text[i][0]);
}
Related
I'm learning C and I've a problem with this school homework.
I have to make function which get two strings from user as parameters. The function removes all spaces from the first string and returns the "cleaned" strings as the other parameter.
The main function ask three strings, uses function to remove spaces and prints "cleaned" strings.
My code doesn't work as it should? What goes wrong?
#include <stdio.h>
void removeSpaces(char *, char *);
int main(){
int i, j;
char string[101], strings[1][101];
for(i = 0; i <= 2; i++){
fgets(string, 100, stdin);
for(j = 0; string[j] != '\0'; j++){
strings[i][j] = string[j];
}
strings[i][j] = '\0';
removeSpaces(strings[i], strings[i]);
}
for(i = 0; i <= 0; i++){
for(j = 0; j <= 101; j++){
printf("%c", strings[i][j]);
}
}
}
void removeSpaces(char *string1, char *string2){
int i, j;
for(i = 0; string1[i] != '\0'; i++){
if(string1[i] != ' '){
string2[i] = string1[j];
j++;
}
}
string2[i] = '\0';
}
You have to be more careful when writing code. There are several things wrong:
In removeSpaces(), you never initialize j. So it can be anything.
You are also mixing up i and j inside removeSpaces(). i should only be used to index string1, and j only for string2.
strings[1][101] is only one string, not 3. But the first for-loop in main() runs 3 times.
You don't have to print strings character by character, just printf("%s", strings[i]) or fputs(strings[i], stdout).
I'm not sure why you used a two-dimensional array strings here. You only need two strings. Renaming the variables can also help you avoid getting confused. Consider:
#include <stdio.h>
static void removeSpaces(const char *input, char *output) {
int i, o;
for(i = 0, o = 0; input[i] != '\0'; i++) {
if(input[i] != ' ') {
output[o] = input[i];
o++;
}
}
output[o] = '\0';
}
int main() {
char input[100], output[100];
fgets(input, sizeof input, stdin);
removeSpaces(input, output);
fputs(output, stdout);
}
Just implementing a simple sorting algorithm to sort a string. I tried printing out the buff char array with printf("%s\n") but it came out blank. The contents of the array are there, though, and I checked with printing out each character of it. What am I missing here?
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char const *argv[])
{
if (argc != 2)
{
printf("usage: ./sortstring string");
exit(1);
}
int size = 1; // 1 to account for '\0'
for (int i = 0; argv[1][i] != '\0'; i++)
{
size += 1;
}
char buff[size];
strcpy(buff, argv[1]);
char temp;
for (int i = 0; i < size; i++)
{
for (int j = i + 1; j < size; j++)
{
if (tolower(buff[i]) > tolower(buff[j]))
{
temp = buff[i];
buff[i] = buff[j];
buff[j] = temp;
}
}
}
// printf("%s\n", buff);
for (int i = 0; i < size; i++)
{
printf("%c", buff[i]);
}
return 0;
}
Change "%c" to "%d" in printf and see the result.
for (int i = 0; i < size; i++)
{
printf("%d", buff[i]);
}
strcpy copies terminating null byte with the source string.
You sorted terminating null byte with other characters.
Your sorting function is probably sorting the null character to position 0.
Instead of attempting to manually count characters in "argc[1]", you could just use the "strlen" function. So, instead of
int size = 1; // 1 to account for '\0'
for (int i = 0; argv[1][i] != '\0'; i++)
{
size += 1;
}
You could use
int size = strlen(argv[1]);
Regards.
The problem is that you're initializing size with 1. I know you did that because you need one more char to \0, but after that, either you need to loop through size - 1 or you can decrease the value of size before your for loops.
Another thing you can do is: initialize size with 0, and use size + 1 while creating your array.
So the following is a sandbox program. The issue I'm having is combining an array into a single string. I would like to do something similar to the code below:
for (i = 0; i < size_of_array; i++)
{
string += A[i]; // print array
}
The goal is to run a command using popen() and capture the output into a single string. the reason for this is so that I can return the output to a separate function for example:
run_command()
{
return output;
}
main()
{
run_command()
}
Now the exact code that the "sandbox" program is using is down below:
#include <stdio.h>
#include <string.h>
int main()
{
FILE *in;
extern FILE *popen();
char buff[512];
int i, size_of_array;
char A[512][512];
in = popen("ls -lt", "r"); // run command
i = 0;
while(fgets(buff, sizeof(buff), in)!=NULL) // get output into buff
{
strcpy(A[i], buff); // copy buff into array
i ++;
}
pclose(in);
size_of_array = i; // get length or size of array
for (i = 0; i < size_of_array; i++)
{
printf("A[%d]= %s", i, A[i]); // print array
}
return 0;
}
I apologize if this is a noob question, I appreciate the help, thank you!
strcat, strcat_s, or strncat append a string at the end of a destination string (cf. cppreference for strcat). The only thing is to make sure that the destination buffer is large enough. strcat_s can be used to avoid buffer overflows, but is not available on all systems. strncat can be used to avoid buffer overflows, too, yet one needs to track the length of the string within the buffer:
#define maxSize 512*512
char result[maxSize] = { 0x0 };
for (int i = 0; i < size_of_array; i++) {
strcat(result, A[i]);
}
or:
char result[maxSize] = { 0x0 };
for (int i = 0; i < size_of_array; i++) {
strcat_s(result, maxSize, A[i]);
}
or:
char result[maxSize] = { 0x0 };
for (int i = 0; i < size_of_array; i++) {
strncat(result, A[i], maxSize-strlen(result)-1);
}
This question already has answers here:
Function to reverse string in C
(4 answers)
Closed 6 years ago.
Beginner programmer here. I'm trying to take an input from user, reverse it and show the result. For some reason, it's printing blanks instead of the reversed string. I know that array[i] has the right information because if I use this loop on line for (int i=0; i<count; i++), it's printing the right characters. It's just not printing in reverse. What am I not getting here?
#include <stdio.h>
#include <cs50.h>
#include <string.h>
int main(void)
{
printf("Please enter a word: ");
char *word = get_string();
int count = strlen(word);
char array[count];
for (int i=0; i< count; i++)
{
array[i] = word[i];
}
for (int i=count-1; i==0; i--)
{
printf("%c ", array[i]);
}
printf("\n");
}
for (int i=0; i< count; i++)
{
array[i] = word[i];
}
You go over the string and copy it, you do not reverse it.
There is also a subtle bug in-waiting in your declaration of array, since you do not leave space for the '\0' character terminator. Passing your buffer to printf as a C-string, as opposed to character by character will have undefined behavior.
So to fix those two particular errors:
char array[count + 1];
array[count] = '\0';
for (int i = 0; i< count; i++)
{
array[i] = word[count - i];
}
As a side note, it may not mean much to use a VLA for this small exercise, but for larger inputs it could very well overflow the call stack. Beware.
// the header where strlen is
#include <string.h>
/**
* \brief reverse the string pointed by str
**/
void reverseString(char* str) {
int len = strlen(str);
// the pointer for the left and right character
char* pl = str;
char* pr = str+len-1;
// iterate to the middle of the string from left and right (len>>1 == len/2)
for(int i = len>>1; i; --i, ++pl, --pr) {
// swap the left and right character
char l = *pl;
*pl = *pr;
*pr = l;
};
};
And just call the function:
int main(void) {
printf("Please enter a word: ");
char *word = get_string();
// Just call the function. Note: the memory is changed, if you want to have the original and the reversed just use a buffer and copy it with srcpy before the call
reverseString(word)
printf("%s\n", word);
};
And just change
char array[count];
for (int i=0; i< count; i++)
{
array[i] = word[i];
}
to
// add an other byte for the null-terminating character!!!
char array[count+1];
strcpy(array, word);
This program is supposed to read in 10 strings and print the ones that end in "ed" however even though it compiles,I keep getting a segmentation fault after I enter my first string. I've tried everything and I just cant figure out why. Heres my code:
#include <stdio.h>
#include <string.h>
int main(void)
{
//Declaration of array of strings
char *strings[10];
int i = 0;
int len = 0;
//Prompts user to enter 10 strings
printf("Enter 10 strings: \n");
//Loop to read in 10 strings
for( i = 0; i < 10; i++)
{
fgets(strings[i], 100, stdin);
}
//Loop to traverse array of strings and print those ending with 'ed'
printf("The strings that end with ed are:\n");
for( i=0; i < 10; i++)
{
len=strlen(strings[i]);
len=len-1;
if(*strings[len] =='e' && *strings[len-1] =='d')
{
printf("%s", strings[i]);
}
}
return 0;
}//End of function main
You have not allocated memory for string elements. Allocate memory for it.
for(int i = 0; i < 10; i++)
strings[i] = malloc(100);
At the end do not forget to free the allocated memory using free.
for(int i = 0; i < 10; i++)
free(string[i]);
Memory is not allocated for string variable string. You only declared pointer to 10 strings
char *strings[10];
There is no memory for the string array or variable hence you have to allocate it
for(i=0;i<10;i++) {
string[i]=malloc((max_length_of_string));
}
You can take max_length_of_string to be 100.
Define the array the following way
char strings[10][100];
Also this code snippet is incorrect
for( i=0; i < 10; i++)
{
len=strlen(strings[i]);
len=len-1;
if(*strings[len] =='e' && *strings[len-1] =='d')
{
printf("%s", strings[i]);
}
}
Try the following
for( i=0; i < 10; i++)
{
len=strlen(strings[i]);
if ( len && strings[i][len - 1] == '\n' ) --len;
if ( len > 1 && strings[i][len - 1] =='d' && strings[i][len-2] =='e')
{
printf("%s", strings[i]);
}
}
Here is an example of how the program could look
#include <stdio.h>
#include <string.h>
int main( void )
{
//Declaration of array of strings
const size_t N = 10;
const size_t M = 100;
char strings[N][M];
size_t i;
size_t len;
//Prompts user to enter 10 strings
printf( "Enter %u strings: \n", N );
//Loop to read in 10 strings
for ( i = 0; i < N; i++ )
{
fgets( strings[i], M, stdin );
}
//Loop to traverse array of strings and print those ending with 'ed'
printf( "The strings that end with ed are:\n" );
for ( i = 0; i < N; i++ )
{
len = strlen( strings[i] );
if ( len && strings[i][len - 1] == '\n' ) --len;
if ( len > 1 && strings[i][len - 1] =='d' && strings[i][len - 2] =='e' )
{
printf( "%s", strings[i] );
}
}
return 0;
}
If to input
apple
room
horse
finished
close
chicken
city
done
success
opened
then the output will be
finished
opened
Some of these issues might be beyond the scope of your project.
You do not allocate any memory for your strings.
You pass an uninitialized pointer to fgets().
You do not adequately handle the problem of the input string being very long (more than 99 characters).
You do not adequately handle the problem of the input string being very short (fewer than 2 characters).
You do not adequately handle the problem of the input having fewer than the expected number or strings.
You do not adequately deal with the issue of fgets() including the newline of the input in the end of the resulting string.
You improperly use strings[len] when you mean strings[i][len].
You are checking for "de" instead of "ed" as intended.
Below is one possible solution to resolve these problems:
int
main (void)
{
char *strings[10] = {}, *x;
int i;
size_t len;
puts("Enter 10 strings:");
for (i = 0; i < 10; ++i) getline(&strings[i], &len, stdin);
puts("The strings that end with ed are:");
for (i = 0; i < 10; ++i) {
if ((x = strings[i])) {
len = strlen(x);
if (x[len-1] == '\n') x[--len] = '\0';
if (len > 1 && strcmp(x + len - 2, "ed") == 0) puts(x);
free(x);
}
}
return 0;
}