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];
}
Related
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.
I want to remove all the repeated characters from array. here is example.
"aabccdee"
"bd"
I'm doing this C language. use only array, loop, if,else(conditional statements) not using pointer.
#include<stdio.h>
int main() {
char c[10];
char com[10] = {0,};
char result[10] = { 0, };
int cnt = 0;
for (int i = 0; i < 10; i++) {
scanf("%c", &c[i]);
}
for (int i = 0; i < 10; i++) {
for (int j = i+1; j < 10; j++) {
if (c[i] == c[j]) {
com[i] = c[i];
cnt++;
printf("%c", com[i]);
}
}
}
for (int i = 0; i < cnt; i++) {
for (int j = 0; j < 10; j++) {
if (com[i] != c[j]) {
result[j] = c[j];
}
}
}
printf("\n");
for (int i = 0; i < 10; i++) {
printf("%c", result[i]);
}
}
I thought this
Make repeated array
Compare original array to repeated array
Output
But repeated array loop can't looping all original array.
How can I do remove all repeated character?
Not good SO policy to blatantly answer homework, but I rarely do it and thought this was an interesting task. Certainly making no claims on efficiency, but it looks like it works to me. As far as I can tell, the first and last cases are corner cases, so I handle those individually, and use a loop for everything in the middle. If you're not allowed to use strlen, then you can roll your own or use some other method, that's not the primary focus of this problem (would be best to fgets the string from a command line argument).
#include <stdio.h>
#include <string.h>
int main(void)
{
char source[] = "aabccdee";
char result[sizeof(source)] = { 0 };
unsigned resultIndex = 0;
unsigned i = 0;
// do this to avoid accessing out of bounds of source.
if (strlen(source) > 1)
{
// handle the first case, compare index 0 to index 1. If they're unequal, save
// index 0.
if (source[i] != source[i+1])
{
result[resultIndex++] = source[i];
}
// source[0] has already been checked, increment i to 1.
i++;
// comparing to strlen(source) - 1 because in this loop we are comparing the
// previous and next characters to the current. Looping from 1 to second-to-the-
// last char means we stay in bounds of source
for ( ; i < strlen(source) - 1; i++)
{
if (source[i-1] != source[i] && source[i] != source[i+1])
{
// write to result if curr char != prev char AND curr char != next char
result[resultIndex++] = source[i];
}
}
// handle the end. At this point, i == the last index of the string. Compare to
// previous character. If they're not equal, save the last character.
//
if (source[i] != source[i-1])
{
result[resultIndex] = source[i];
}
}
else if (strlen(source) == 1)
{
// if source is only 1 character, then it's trivial
result[resultIndex] = source[i];
}
else
{
// source has no length
fprintf(stderr, "source has no length.\n");
return -1;
}
// print source and result
printf("source = %s\n", source);
printf("result = %s\n", result);
return 0;
}
Various outputs for source:
source = "aabccdee"
result = "bd"
source = "aaee"
result =
source = "a"
result = "a"
source = "abcde"
result = "abcde"
source = "abcdee"
result = "abcd"
source = "aabcde"
result = "bcde"
source = "aaaaaaaaaaaabdeeeeeeee"
result = "bd"
source = ""
source has no length.
first of all before we speak , you have to check this
you need to put a whitespace when scaning a char using scanf
so
scanf("%c", &c[i]);
becomes
scanf(" %c", &c[i]);
secondly your idea is kinda a messy as the result showed you're only handling cases and it doesn't continue verifying the whole array . you need to learn how to shift an array to the right or left
your issue later on that when you shift your table(not completely) you still print out of the size .
so bascilly in general your code should be something like this :
#include<stdio.h>
int main() {
char c[10];
int length=5;
for (int i = 0; i < 5; i++) {
scanf(" %c", &c[i]);
}
int j,k,i;
for(i=0; i<length; i++)
{
for(j=i+1; j<length; j++)
{
if(c[i] == c[j])
{
length--;
for(k=j; k<length; k++)
{
c[k] = c[k + 1];
}
j--;
}
}
}
printf("\n");
for (int i = 0; i < length; i++) {
printf("%c", c[i]);
}
}
you simply take one case and compare it to the rest , if it exists you shift from the position you find for the second time the element and so on
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);
}
I am trying to write a program which merges a lines from stdin and print only those sentences which are longer than 80 characters. The first found line works well - the later ones, however, are empty. I think that I am doing something wrong with the line
current_sentence = malloc(sentence_len);.
How can I reassign a string correctly?
Code
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# define BUFFERSIZE 100
char* merge_string(char *text[], int n){
int i;
char *result = malloc(BUFFERSIZE * n);
for (i=0; i < n; i++){
strcat(result, text[i]);
}
return result;
}
int main(int argc, char *argv[]){
char buffer[BUFFERSIZE];
int i = 0;
char *text[BUFFERSIZE];
while(fgets(buffer, BUFFERSIZE, stdin) != NULL){
text[i] = strdup(buffer);
i++;
}
char *sentence = merge_string(text, i);
int sentence_len = strlen(sentence);
int j = 0;
int counter = 0;
char *current_sentence = malloc(sentence_len);
while (j < sentence_len){
current_sentence[counter] = sentence[j];
if (sentence[j] == '\n' && counter >= 80){
printf(":::HIT:::%s\n\n\n", current_sentence);
counter = 0;
current_sentence = malloc(sentence_len);
}
else if (sentence[j] == '\n'){
puts("Resetting counter");
counter = 0;
}
j++; counter++;
}
return 0;
}
Output
make 1_17; ./1_17 < example.txt
make: `1_17' is up to date.
Resetting counter
Resetting counter
:::HIT:::SHenri Cartier-Bresson (1908-2004) said "Your first 10,000 photographs are your worst," but he shot more than one an hour.)
Resetting counter
:::HIT:::
Resetting counter
:::HIT:::
You are not terminating current_sentence with a null character ('\0'). If you want printf to print the string properly, better make sure it is null-terminated.
By the way, there's no need for a second malloc. Reuse the memory allocated for current_sentence without re-allocating.
Also note that you're not freeing the allocated memory properly. You should be use a matching free call for each malloc. Perhaps this isn't a problem now, but it creates a memory leak.
Your loop should look something like this:
while (j < sentence_len)
{
current_sentence[counter] = sentence[j];
if (sentence[j] == '\n')
{
if (counter >= 80)
{
current_sentence[counter + 1] = '\0'; // Make string null-terminated
printf(":::HIT:::%s\n\n\n", current_sentence);
}
else
{
puts("Resetting counter");
}
counter = 0;
}
else
{
counter++;
}
j++;
}
free(current_sentence); // Free allocated memory
Then again, as mentioned in a comment, you'd rather let fgets do the work for you indeed.
char *text[BUFFERSIZE];
should be
char text[BUFFERSIZE];
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
}
}