How to convert array contents into a single string C - c

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);
}

Related

In c, when I use %s to print out the contents of a char array it prints blank, but when I loop over it and print each character it works

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.

Cant get first character in array of strings

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]);
}

Adding every other element from one array to another in C

so I read in a string of characters from a file into an array called source. Now I want to split that array into 2 other more arrays, one containing all of the even indexes and the other containing the odd indexes of the source array.
This is the code i currently have, and I'm trying to accomplish this in the reachable function.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "graph.h"
void getfile(char[], char[]);
void reachable(char[]);
int size;
int i;
////////////GETFILE FUNCTION/////////////
void getfile(char *graph, char *source) {
FILE *infile;
infile = fopen(graph, "r");
if (infile == NULL) {
fprintf(stderr, "Can't open input file %s!\n", graph);
exit(1);
}
while (fscanf(infile, "%s", &source[i]) != EOF) {
++i;
}
fclose(infile);
size = strlen(source);
printf("%s\n", source);
reachable(&source[0]);
}
///////////REACHABLE FUNCTION////////////
void reachable (char *source){
char odd[100];
odd[100] ='\0';
char even[100];
even[100] = '\0';
for (i = 0; i<size; i+=2){
// printf("%c", source[i]); // when I run this line, I get the output I want
odd[i] = source[i]; // so why doesn't this put the output into the odd array?
}
for (i = 1; i<size; i+=2){
even[i] = source[i];
}
printf("%s\n", odd);
// printf("%s\n", even);
}
Any ideas why this doesn't work?
This is the string stored in source:
rlxrtgacufkrzyngilzxazrasjsbjqqitxmewplhtwzgxhokfmadrv
and this is the output I want for even and odd.
even: lrgcfryglxzajbqixephwghkmdv
odd: rxtaukznizarssjqtmwltzxofar
Any ideas on how to do this?
Thanks in advance!
You insert the values into odd and even at the exact same place as it is originally stored in source.
You need to have another counter than i for the destination array:
int destPlace = 0;
for (i = 1; i<size; i+=2) {
odd[destPlace] = source[i];
destPlace++;
}
And then the same procedure for even array.
Please note that in your code, both odd and even start on the same index, and it's not even the first which is source[0].
All right, assuming you did code you main function correctly,
Check:
char odd[100];
odd[99] ='\0'; //odd array has index from 0 to 99, not 100
char even[100];
even[99] = '\0'; //same here
You have to keep track of both odd/even index and source index.
int spliti, srci;
spliti=0, srci=0; // odd index starts with 0 in C
while (srci < size) {
odd[spliti] = source[srci];
spliti++;
srci+=2;
}
odd[spliti] = '\0';
spliti=0, srci=1; // even index starts with 1 in C
while (srci < size) {
even[spliti] = source[srci];
spliti++;
srci += 2;
}
even [spliti] = '\0';
There is a mistake in for loop in reachable function. For even you should start the loop at I=0 and increment by 2. For odd index you have to start the loop at i=1 and increment by 2. I think the code should be look like this:
for (i = 1; i<size; i+=2) {
odd[i] = source[i];
}
for (i = 0; i<size; i+=2) {
even[i] = source[i];
}

Segment fault while reading a string into a char* array

I am trying to read some strings and then print them into a matrix form.
int main(int argc, char **argv)
{
char *buffer[BUFFER_SIZE];
for(size_t i = 0; i < BUFFER_SIZE; i++)
{
scanf("%s",buffer[i]); /**This line is causing segment fault **/
}
for(size_t i = 0; i < BUFFER_SIZE; i++)
{
for(size_t j = 0; j < strnlen(buffer[i], MAX); j++ )
{
printf("%c ",buffer[i][j]);
}
printf("\n");
}
}
Any suggestion what I am missing here?
char *buffer[BUFFER_SIZE] is an array of character pointers. The way your code is now, buffer[i] is a char * that is uninitialized at the time you scanf("%s",buffer[i]). You need to allocate memory (malloc, perhaps) for scanf to store the string of characters prior to this point.

Printing Array of Strings

I'm parsing a text file:
Hello, this is a text file.
and creating by turning the file into a char[]. Now I want to take the array, iterate through it, and create an array of arrays that splits the file into words:
string[0] = Hello
string[1] = this
string[2] = is
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "TextReader.h"
#include <ctype.h>
void printWord(char *string) {
int i;
for (i = 0; i < strlen(string); i ++)
printf("%c", string[i]);
printf("\n");
}
void getWord(char *string) {
char sentences[5][4];
int i;
int letter_counter = 0;
int word_counter = 0;
for (i = 0; i < strlen(string); i ++) {
// Checks if the character is a letter
if (isalpha(string[i])) {
sentences[word_counter][letter_counter] = string[i];
letter_counter++;
} else {
sentences[word_counter][letter_counter + 1] = '\0';
word_counter++;
letter_counter = 0;
}
}
// This is the code to see what it returns:
i = 0;
for (i; i < 5; i ++) {
int a = 0;
for (a; a < 4; a++) {
printf("%c", sentences[i][a]);
}
printf("\n");
}
}
int main() {
// This just returns the character array. No errors or problems here.
char *string = readFile("test.txt");
getWord(string);
return 0;
}
This is what it returns:
Hell
o
this
is
a) w
I suspect this has something to do with pointers and stuff. I come from a strong Java background so I'm still getting used to C.
With sentences[5][4] you're limiting the number of sentences to 5 and the length of each word to 4. You'll need to make it bigger in order to process more and longer words. Try sentences[10][10]. You're also not checking if your input words aren't longer than what sentences can handle. With bigger inputs this can lead to heap-overflows & acces violations, remember that C does not check your pointers for you!
Of course, if you're going to use this method for bigger files with bigger words you'll need to make it bigger or allocate it dymanically.
sample that do not use strtok:
void getWord(char *string){
char buff[32];
int letter_counter = 0;
int word_counter = 0;
int i=0;
char ch;
while(!isalpha(string[i]))++i;//skip
while(ch=string[i]){
if(isalpha(ch)){
buff[letter_counter++] = ch;
++i;
} else {
buff[letter_counter] = '\0';
printf("string[%d] = %s\n", word_counter++, buff);//copy to dynamic allocate array
letter_counter = 0;
while(string[++i] && !isalpha(string[i]));//skip
}
}
}
use strtok version:
void getWord(const char *string){
char buff[1024];//Unnecessary if possible change
char *p;
int word_counter = 0;
strcpy(buff, string);
for(p=buff;NULL!=(p=strtok(p, " ,."));p=NULL){//delimiter != (not isaplha(ch))
printf("string[%d] = %s\n", word_counter++, p);//copy to dynamic allocate array
}
}

Resources