Exiting Do While loop - c

I was working on some homework, and came across this issue.
Write a program that reads several lines of text and prints a table indicating the number of one-letter words, two-letter words,
three-letter words, and so on, appearing in the text. For example the
phrase "Whether 'tis nobler in the mind to suffer"
Will contain
1 letter words: 0
2 letter words: 2
3 letter words: 1
4 letter words: 2 (including 'tis)
5 letter words: 0
6 letter words: 2
7 letter words: 1
My code for the question is below.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXDIMENSIONS 1000 //set max dimensions
#define MAXLENGTH 1000 //set max length
void separate(char stringArray[][MAXLENGTH], int words);
void printTable(char stringArray[][MAXLENGTH], int c);
int main(int argc, char** argv) {
char txt[MAXLENGTH];
char *token;
char mat[MAXDIMENSIONS][MAXLENGTH];
int i=0,wordcount=0;
do{
printf(">>>Write and press enter (EXIT for end of program)<<< : ",49);
fgets(txt,sizeof txt,stdin);
if(strcmp(txt,"EXIT")!=0)
{
token=strtok(txt," ");
strcpy(mat[i],token);
i++;
while(token!=NULL){
token=strtok(NULL, " ");
if(token!=NULL){
strcpy(mat[i],token);
i++;
}
}
}
}while(strcmp(txt,"EXIT")!=0);
separate(mat,i);
printTable(mat,i);
return (EXIT_SUCCESS);
} // end of main
void separate(char stringArray[][MAXLENGTH], int words){
for(int i=0; i<words; i++){
for(int j=0; j<strlen(stringArray[i]); j++){
if((stringArray[i][j]<65 && stringArray[i][j]!=39) || (stringArray[i][j]>90 && stringArray[i][j]<97)|| stringArray[i][j]>122){
for(int g=j; g<strlen(stringArray[i]); g++){
stringArray[i][g]=stringArray[i][g+1];
}
}
}
}
}
void printTable(char stringArray[][MAXLENGTH], int c){
int max;
int value=0,j;
max=strlen(stringArray[0]);
for(int i=1; i<c; i++){
if(max<strlen(stringArray[i])){
max=strlen(stringArray[i]);
}
}
printf("\n***********WORD LENGTH READER***********\n");
printf("| LENGTHS || VALUES | \n");
for(j=1; j<=max; j++){
for(int i=0; i<c; i++){
if(strlen(stringArray[i])==j){
value++;
}
}
printf("| %d || %d | \n",j,value);
value=0;
}
printf("\n****************************************\n");
}
My issue is getting out of the do while loop on line 17-33. It is my first time using fgets and I believe that this is probably what is causing the issue. I had written the code using gets and it works like that, but I know that gets is not supposed to be used due to its vulnerability.
Any help is appreciated.
Thanks in advance!

Because fgets also reads the newline, your exit condition will not be met because of the newline. You can either include the newline in your check, "EXIT\n" or you can patch out the newline after fgets.
The following example also makes the loop a bit simpler:
do {
fgets(txt,sizeof txt,stdin);
char *p= strrchr(txt,'\n'); if (p) *p= '\0';
if(strcmp(txt,"EXIT")==0)
break;
//....
while(1);

Related

printing characters using array in c language?

I tried to scan and print the characters of array using below code but input characters are not matching with output characters
#include <stdio.h>
int main() {
char s[10];
int i, n;
printf("enter the value of n:\n");
scanf("%d", &n);
printf("start entering the characters:\n");
for (i = 0; i < n; i++) {
scanf("%c", &s[i]);
}
for (i = 0; i < n; i++) {
printf("%c", s[i]);
}
return 0;
}
OUTPUT
enter the value of n:
5
start entering the characters:
ABCDE(scanf values)
ABCD(printf values)
Can anyone please clarify my doubt why is the output not matching with input
Since you are wanting to read data into a character array with "scanf" you probably could just reference the string identifier instead and simplify things. Following are a few tweaks to your code that still inputs the data and prints it back out.
#include <stdio.h>
#include <string.h>
int main()
{
char s[10];
int i, n;
printf("enter the value of n:\n");
scanf("%d", &n);
printf("start entering the characters:\n");
scanf("%s", s); /* In lieu of using a loop */
if (strlen(s) < n) /* Just in case less characters are entered than was noted */
n = strlen(s);
for (i = 0; i < n; i++)
{
printf("%c", s[i]);
}
printf("\n");
return 0;
}
The program just scans in the complete string instead of a character at a time. Also, I included the "<string.h> file so as to use functions such as "strlen" (get the length of the string) to provide a bit more robustness to the code. Running the program netted the same character set that was entered.
:~/C_Programs/Console/InputOutput/bin/Release$ ./InputOutput
enter the value of n:
7
start entering the characters:
ABCDEFG
ABCDEFG
You might give that a try.
Regards.

C program prints garbage characters

I have an assignment to write a program in C that functions similarly to the bash sed 's/oldstring/newstring/g' but only using stdio.h and string.h. We cannot use malloc s we have not yet covered it in class. The program has to continue to take user input until the user enters ^D. We're using GCC so I have it set up to use variable length arrays and I've managed to get the program to find and replace a single instance of oldstring in the user input. However, on occasion the program will output some garbage characters and I am not sure why. I assume it is a memory allocation error or the program is reading past where I want it to read. The code is below:
#include <stdio.h>
#include <string.h>
int isMatch(char * os, char * us){
int i;
char temp[strlen(os)];
for(i=0; i<strlen(us); i++){
int k=0;
for(int j=i; j<i+strlen(os); j++){
temp[k]=us[j];
k++;
}
if(strcmp(temp, os)==0){
return 1;
}
else{
return 0;
}
}
}
void replace(char * os, char * us, char * ns, int loc){
char out[strlen(us) - (strlen(os) - strlen(ns))];
int i;
for(i=0; i<loc; i++){
out[i]=us[i];
}
int k=0;
for(i=loc; i<loc+strlen(ns); i++){
out[i]=ns[k];
k++;
}
k=0;
for(i=loc+strlen(ns); i<strlen(us)-(strlen(os)-strlen(ns)); i++){
out[i]=us[loc+strlen(os)+k];
k++;
}
printf("%s\n", out);
}
int main(int argc, char * argv[]){
char input[100];
int i;
char c;
int match;
while(1){
if(scanf("%c", &c)==EOF){
break;
}
if((input[0]=c) != '\n'){
for(i=1; i<100; i++){
scanf("%c", &input[i]);
if(input[i]=='\n'){
break;
}
}
}
for(i=0; i<100; i++){
match = isMatch(argv[1], &input[i]);
if(match == 1){
replace(argv[1], input, argv[2], i);
}
if(input[i]=='\n'){
break;
}
}
}
}
I call the program with ./a.out aa b for example.
I then enter helaalo and the program spits out helblo which is correct. I then enter libraary and the program outputs librbry followed by some random characters on new lines. I then enter caar and the program outputs cbr followed by even more random letters on new lines. A screenshot of this behavior is included.
Since you can't use malloc, you can force to add terminating \0 for the end of input string and end of out string,
// input
for(i=1; i<100; i++){
scanf("%c", &input[i]);
if(input[i]=='\n'){
input[i] = '\0'; // add terminating \0 for input
break;
}
}
// out
for(i=loc+strlen(ns); i<strlen(us)-(strlen(os)-strlen(ns)); i++){
out[i]=us[loc+strlen(os)+k];
k++;
}
int len = strlen(us)-(strlen(os)-strlen(ns));
out[len] = '\0'; // for out termiante \0
printf("%s\n", out);
The problem is coming from your the way you are filling your input buffer. You don't add a \0 at the end of the string.
There is also an other "problem", when you declare you array out if you want a dynamic size you need to use a malloc. how you are declaring it will not have a dynamic size , the size of the array will be calculated at compilation time. Just to keep it in mind.

C program to generate pseudolanguage - global 3D array is too large (segmentation fault)?

I am supposed to write a program which prints a text in pseudo-English by parsing an existing English text and looking at the last two letters printed to determine what the next one will probably be (the first to are imagined as '.' and ' '). For that task, I came up with the following code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
short characters[256][256][256];
int main(int argc, char* argv[]){
if(argc<2){
printf("In addition to the input file and maybe output file, please enter the number of output sentences as a command line argument.\n");
return 1;
}
/*Different approach where I malloced the array instead, same result*/
/*short ***characters=malloc(256 * sizeof(short**));
for(int i=0; i<256; i++){
*characters[i]=malloc(256 * sizeof(short*));
for(int i2=0; i2<256; i++){
characters[i][i2]=malloc(256 * sizeof(short**));
}
}*/
/*Read text*/
char a='.', /*pre-previous character*/
b=' ', /*previous character*/
c; /*current character*/
int n=0;
while((c=getchar())!=EOF){
characters[a][b][c]++;
a=b;
b=c;
n++;
}
/*Check how many sentences should be printed*/
int sentences=0, multiplier=1;
for(int i=0; i<sizeof(argv[1])/8; i++){
sentences+=argv[1][i]*multiplier;
multiplier*=10;
}
/*Print text*/
int currentsentences=0, random, p1, p2;
a='.';
b=' ';
while(currentsentences<sentences){
int uninitialized;
srand(time(0)+p1+p2+uninitialized); /*adds a bit of entropy*/
random=rand()%n;
p1=0;
for(int i=0; ; i++){
p2=p1+characters[a][b][i];
if(random>p1 && random<=p2){
c=characters[a][b][i];
p1+=characters[a][b][i];
break;
}
}
putchar(c);
if(c=='.' || c=='?' || c=='!')
currentsentences++;
a=b;
b=c;
}
return 0;
}
It compiles without errors or warnings, however, when I try to run this program, it always returns a segfault before printing anything, unless I do not enter enough command line arguments, in which case it enters the first if clause. This is why I think it has to do something with the 3D array, as it seems not being able to even enter the first loop (if I let it print something before that, it won't). It is needed to be that large, as the structure is the following: [pre-previous letter][previous letter][current letter]=how often did this constellation occur. As I probably would not need higher ASCII and the range of char would probably have been enough, I tried char instead of short and an array of 128*128*128 - same result. Running it as root did not change much and the same goes for increasing ulimit. However, aren't global variabloes saved in the heap? The use of malloc(), which I commented out above, did not change anything as well. I have tried this on two machines, one OS: X, 64 Bit and 8GB DDR3, the other one Linux Mint 19.1, 64 Bit and 32GB DDR4. Both the same result, again (MacOS said segmentation fault: 11, Linux said segmentation fault (core dumped)). As the used memory of that array is about 33 MB, my RAM cannot be the problem either. So why is there a segfault? Do I need to allocate more RAM to the heap (I do not think this is even possible)? Is it maybe something that has not to do with the array and/or its size as all?
This is the latest version of the program; still showing the same behavior:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
short characters[256][256][256];
int main(int argc, char* argv[]){
/*Check if number of sentences was given*/
if(argc<2){
printf("In addition to the input file and maybe output file, please enter the number of output sentences as a command line argument.\n");
return 1;
}
/*Different approach with malloc*/
/*short ***characters=malloc(256 * sizeof(short**));
for(int i=0; i<256; i++){
*characters[i]=malloc(256 * sizeof(short*));
for(int i2=0; i2<256; i++){
characters[i][i2]=malloc(256 * sizeof(short**));
}
}*/
/*Read input text*/
int a='.', /*pre-previous character*/
b=' ', /*previous character*/
c; /*current character*/
int n=0;
for(; (c=getchar())!=EOF; n++){
characters[a][b][c]++;
a=b;
b=c;
}
/*Check how many sentences should be printed*/
int sentences=0, multiplier=1;
for(int i=strlen(argv[1])-1; i>=0; i--){
sentences+=(argv[1][i]-'0')*multiplier;
multiplier*=10;
}
/*Print text*/
int currentsentences=0, random, p1=0, p2=0;
a='.';
b=' ';
srand(time(0));
while(currentsentences<sentences){
random=(rand()+p1+p2)%n;
p1=0;
for(int i=0; i<256; i++){
p2=p1+characters[a][b][i]; /*Determine range for character*/
if(random>p1 && random<=p2){ /*Cheack if random number is in range of character*/
c=characters[a][b][i];
p1+=characters[a][b][i];
break;
}
}
putchar(c);
if(c=='.' || c=='?' || c=='!')
currentsentences++;
a=b;
b=c;
}
return 0;
}
UPDATE: An interesting behavior it shows is that, if you add something like printf(„here“) to the very beginning of the of the program, it will output that „here“ if the first if statement if entered. However, if it is not, the program will return a segfault before printing anything.
UPDATE 2: Interestingly, if you do not give an input file and enter everything manually, it will not return a segfault, but also never finish as well.
UPDATE 3: The program now works, see below. Sorry for all the problems I caused and thank you for helping me.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
unsigned int characters[128][128][128];
int main(int argc, char* argv[]){
/*Check if input file was given*/
if(argc<2){
printf("Please enter an input file as command line argument.\n");
return 1;
}
/*Check for input file, open it*/
FILE *fp=NULL;
fp=fopen(argv[1], "r");
if(!fp){
printf("Error 404: Input file not found.\n");
return 404;
}
/*Read input text*/
int a='.'; /*pre-previous character*/
int b=' '; /*previous character*/
int c; /*current character*/
while((c=fgetc(fp))!=EOF){
if(c<127 && c>='\t'){ /*All characters from higher ASCII and system codes ignored. Still uses letters, digits and typical special characters and formatting characters.*/
characters[a][b][c]++;
a=b;
b=c;
}
}
fclose(fp);
/*Check how many sentences should be printed*/
unsigned int sentences;
printf("How many sentences do you want to be printed? ");
scanf("%d", &sentences);
/*Print text*/
unsigned int currentsentences=0, random, p1=0, p2=0, n;
a='.';
b=' ';
srand(time(0));
while(currentsentences<sentences){
n=0;
for(int i='\t'; i<127; i++){
n+=characters[a][b][i];
}
random=(rand()+p1+p2+sentences+currentsentences+clock())%n;
p1=0;
for(int i='\t'; i<127; i++){
p2=p1+characters[a][b][i]; /*Determine range for character in combination with line 58*/
if(random>=p1 && random<p2 && characters[a][b][i]!=0){ /*Check if random number is in range of character and that character occured in that combination*/
c=i;
printf("%c", c);
characters[a][b][c]++; /*Experimental, language will change over time pseudo-randomly*/
break;
}
p1+=characters[a][b][i];
}
if(c=='.' || c=='?' || c=='!')
currentsentences++;
a=b;
b=c;
}
printf("\n");
return 0;
}
The main problem is in this part of the code:
p1=0;
for(int i=0; ; i++){
p2=p1+characters[a][b][i];
if(random>p1 && random<=p2){
c=characters[a][b][i];
p1+=characters[a][b][i];
break;
}
}
Here you keep incrementing i without checking for out of bounds access. You should have something like:
if (i >= 255) { // error handling ....};
Also notice that p1 in the loop is always zero.
In this part
random=(rand()+p1+p2)%n;
p1 and p2 is uninitialized so you may end up with a negative number which obviously means that you never hit the break statement. In other words - an endless loop where you keep incrementing i (which leads to out of bounds access).
As an example I changed the code like:
for(int i=0; ; i++){
printf("random=%d p1=%d a=%c b=%c i=%d", random, p1, a, b, i);
and got output like:
...
random=-3 p1=0 a=. b= i=42484 p2=0
random=-3 p1=0 a=. b= i=42485 p2=0
random=-3 p1=0 a=. b= i=42486 p2=0
random=-3 p1=0 a=. b= i=42487 p2=0
...
Notice that random is negative so the loop can never terminate.
Warnings, Errors and some very good suggestions are pointed out in the comments under your post. nota bene.
The following comment statement seems clear enough,
/*Check how many sentences should be printed*/
but it was not clear to me what was being done in the following snippet of your code to accomplish that:
int sentences=0, multiplier=1;
for(int i=0; i<sizeof(argv[1])/8; i++){
sentences+=argv[1][i]*multiplier;
multiplier*=10;
}
So the following short snippet is a suggestion for a different approach:
// assume at minimum input of one legal filespec,
// eg: .\\filename.txt (Windows) or ./filename.txt (Linux)
int main(int argc, char *argv[])
{
FILE *fp = NULL;
int c = 0;
int sentences = 0;
if(argc<2)
{
printf("Minimum command line usage: <name>.exe [pathFileName]. Program exiting.");
getchar();
return 0;
}
fp = fopen(argv[1], "r");
if(fp)
{
c = fgetc(fp);
while(c) // will exit upon EOF (-1) Note c is int, not char
{
if( (c=='.') || (c=='?') || (c=='!') )
{
sentences++;
}
}
fclose(fp);
}
else return 0; //error, file not opened.
/* rest of your code here */
return 0;
}
The entire logic for selecting the next character is wrong:
After the loop iterating i to examine characters[a][b][i], the code sends c to output. At that point, c is either left over from some previous code or is characters[a][b][i] for some i, which means it is a count of triples that were seen during analysis—it is not a code for the character that should be printed.
The code for preparing p1 and p2 and comparing them to a random number is nonsensical. The code ought to pick a random number in [0, N), where N is the sum of characters[a][b][i] for all character codes i and then select the character code c such that c is in [p1, p2), where p1 is the sum of characters[a][b][i] for 0 ≤ i < c and p2 is p1 + characters[a][b][c].

How to sort array of strings in ascending order in C

Problem
I have made sorting program which is similiar to other found at
https://beginnersbook.com/2015/02/c-program-to-sort-set-of-strings-in-alphabetical-order/
but program which i made is not working.
I think both are same but my program giving me waste output.
Also i want to know in other program count is set to 5 for example and it should take 6 input starting from 0 but it is getting only 5,How?
My Program
#include <string.h>
#include <stdio.h>
int main() {
char str[4][10],temp[10];
int i,j;
printf("Enter strings one by one : \n");
for(i=0;i<5;i++)
scanf("%s",str[i]);
for(i=0;i<5;i++)
for(j=i+1;j<5;j++)
if(strcmp(str[i],str[j])>0){
strcpy(temp,str[i]);
strcpy(str[i],str[j]);
strcpy(str[j],temp);
}
printf("\nSorted List : ");
for(i=0;i<5;i++)
printf("\n%s",str[i]);
printf("\n\n");
return 0;
}
Use qsort().
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int pstrcmp( const void* a, const void* b )
{
return strcmp( *(const char**)a, *(const char**)b );
}
int main()
{
const char* xs[] =
{
"Korra",
"Zhu Li",
"Asami",
"Mako",
"Bolin",
"Tenzin",
"Varrick",
};
const size_t N = sizeof(xs) / sizeof(xs[0]);
puts( "(unsorted)" );
for (int n = 0; n < N; n++)
puts( xs[ n ] );
// Do the thing!
qsort( xs, N, sizeof(xs[0]), pstrcmp );
puts( "\n(sorted)" );
for (int n = 0; n < N; n++)
puts( xs[ n ] );
}
Please don’t use bubble sort. In C, you really do not have to write your own sorting algorithm outside of specialized needs.
Here is a program which will sort and print your inputted strings. Answering a little late, but just in case others have a similar question.
// This program will sort strings into either ascending or descending order
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 1000
#define EQUAL 0
#define ASCENDING 0
#define DESCENDING 1
// Function prototypes
void swap_str(char str1[], char str2[]);
void sort_strings(char str[MAX_SIZE][MAX_SIZE], int len, int order_type);
void print_2d_array(char str[MAX_SIZE][MAX_SIZE], int len);
int main(void) {
int order_type;
char str[MAX_SIZE][MAX_SIZE];
// User selecting the order type
printf("-----------[Order Type]-----------\n");
printf("Sort your strings in ascending or descending order?\n");
printf("0 = Ascending | 1 = descending\n");
scanf("%d", &order_type);
if (order_type != ASCENDING && order_type != DESCENDING) {
printf("Please enter 0 or 1\n");
exit(1);
}
// User inputting their strings
printf("---------[Enter Strings]----------\n");
printf("Enter Strings one by one.\n");
printf("Max Strings: %d | Max String Len: %d\n", MAX_SIZE, MAX_SIZE);
int i = 0;
while ((i < MAX_SIZE) && (scanf("%s", str[i]) == 1)) i++;
if (i == MAX_SIZE) printf("You reached the maximum strings allowed\n");
// Program output of the sorted strings
printf("---------[Sorted Strings]---------\n");
sort_strings(str, i, ASCENDING);
print_2d_array(str, i);
return 0;
}
// Swaps two strings (assuming memory allocation is already correct)
void swap_str(char str1[], char str2[]) {
char temp[MAX_SIZE];
strcpy(temp, str1);
strcpy(str1, str2);
strcpy(str2, temp);
}
// Will sort a 2D array in either descending or ascending order,
// depending on the flag you give it
void sort_strings(char str[MAX_SIZE][MAX_SIZE], int len, int order_type) {
int i = 0;
while (i < len) {
int j = 0;
while (j < len) {
if ((order_type == ASCENDING) &&
(strcmp(str[i], str[j]) < EQUAL)) {
swap_str(str[i], str[j]);
} else if ((order_type == DESCENDING) &&
(strcmp(str[i], str[j]) > EQUAL)) {
swap_str(str[i], str[j]);
}
j++;
}
i++;
}
}
// Will print out all the strings 2d array
void print_2d_array(char str[MAX_SIZE][MAX_SIZE], int len) {
int i = 0;
while (i < len) {
printf("%s\n", str[i]);
i++;
}
}
Example (Ascending order):
-----------[Order Type]-----------
Sort your strings in ascending or descending order?
0 = Ascending | 1 = descending
0
---------[Enter Strings]----------
Enter Strings one by one.
Max Strings: 1000 | Max String Len: 1000
Mango
Watermelon
Apple
Banana
Orange
// I pressed CTRL+D here (Linux) or CTRL+Z then enter (on Windows). Essentially triggering EOF. If you typed the MAX_SIZE it would automatically stop.
---------[Sorted Strings]---------
Apple
Banana
Mango
Orange
Watermelon
it should take 6 input starting from 0 but it is getting only 5,How?
This loop
for(i=0;i<5;i++)
scanf("%s",str[i]);
execute for i being 0, 1, 2, 3, 4 so it loops 5 times.
If you want 6 loops do
for(i=0;i<=5;i++)
^
Notice
or
for(i=0;i<6;i++)
^
Notice
Also notice this line
char str[6][10],temp[10];
^
Notice
so that you reserve memory for 6 strings
This is not an answer, but some criticism of the code you refer to:
#include<stdio.h>
#include<string.h>
int main(){
int i,j,count;
char str[25][25],temp[25];
puts("How many strings u are going to enter?: ");
scanf("%d",&count); // (1)
puts("Enter Strings one by one: ");
for(i=0;i<=count;i++) // (2)
gets(str[i]);
for(i=0;i<=count;i++)
for(j=i+1;j<=count;j++){
if(strcmp(str[i],str[j])>0){
strcpy(temp,str[i]);
strcpy(str[i],str[j]);
strcpy(str[j],temp);
}
}
printf("Order of Sorted Strings:"); // (3)
for(i=0;i<=count;i++)
puts(str[i]);
return 0;
}
And the criticism:
(1) scanf("%d",&count); reads a number into count, and returns after that. It does not consume the line break(!)
(2) this loop does not print anything, just reads. However if you put
for(i=0;i<=count;i++){
printf("%d:",i);
gets(str[i]);
}
in its place, you will suddenly see that it asks for names 0...5, just skips the 0 automatically. That is where the line break is consumed, it reads an empty string. You can also make it appear, if instead of putting 5 into the initial question, you put 5 anmoloo7.
(3) in the printout the names appear below the title Order of Sorted Strings. But there is no linebreak in that printf. The thing is that the empty string is "smaller" than any other string, so it gets to the front of the list, and that is printed there first. If you do the 'trick' of appending a name after the initial number, the output will look different, there will be 6 names, and one of them appended directly to the title.
Plus there is the thing what you probably get from your compiler too: gets is a deadly function, forget its existence and use fgets with stdin as appears in other answers.
I have this sample that I made:
#include <stdio.h>
#include <string.h>
void main()
{
char str[100],ch;
int i,j,l;
printf("\n\nSort a string array in ascending order :\n");
printf("--------------------------------------------\n");
printf("Input the string : ");
fgets(str, sizeof str, stdin);
l=strlen(str);
/* sorting process */
for(i=1;i<l;i++)
for(j=0;j<l-i;j++)
if(str[j]>str[j+1])
{
ch=str[j];
str[j] = str[j+1];
str[j+1]=ch;
}
printf("After sorting the string appears like : \n");
printf("%s\n\n",str);
}
#include <stdio.h>
#include <string.h>
#define STRING_MAX_WIDTH 255
void sort_strings(char str_arr[][STRING_MAX_WIDTH],int len){
char temp[STRING_MAX_WIDTH];
for(int i=0;i<len-1;i++){
if(strcmp(&str_arr[i][0],&str_arr[i+1][0])>0){
strcpy(temp, str_arr[i+1]);
strcpy(str_arr[i+1],str_arr[i]);
strcpy(str_arr[i],temp);
sort_strings(str_arr, len);
}
}
}
int main(){
char str_arr[][STRING_MAX_WIDTH] = {"Test", "Fine", "Verb", "Ven", "Zoo Keeper", "Annie"};
int len = sizeof(str_arr)/STRING_MAX_WIDTH;
sort_strings(str_arr, len);
for(int i=0;i<len;i++){
printf("%s\r\n", str_arr[i]);
}
}

Split a string between words and insert newlines

i have a string that is made out of a few sentences.
for example:
hello world bye bye
now, i need to make this sentence into a coulmn of words:
hello
world
bye
bye
i have this idea going on, but i dont know how to write it correctly, so i was hopiny ypu guys could help me out.
this is what i have so far:
int len=0, k=0, stopatspace=0;
char temptext[100][15]={0};
char line[300]={0};
len=strlen(line);
printf("len is: %d", len);
for(k=0; k<len; k++)
{
if (k == ' ')
{
// i dont know what to write here in order to make it a cloumn
}
}
basiclly, my idea is to run on all the length of my line and when i reach a space i want it to enter (to go one line down so that it will look like a coulmn)
Suppose line is the char array that contains hello world bye bye and text is declared as
char text[100][15]; //I used 100 and 15 because your example contains it
and you want each word to be copied into each row of text. Then,use strtok() function with " "(space) as delimeter and place this in a loop that terminates when strtok() returns NULL to get each word. Copy each word to each row of text using strcpy() in the loop.
The code for this will look like this:
char text[100][15];
char line[]="hello world bye bye";
int i=0;
char *token=strtok(line," ");
while(token!=NULL)
{
strcpy(text[i],token);
i++;
token=strtok(NULL," ");
}
Now, to print it,you can use
for(int j=0;j<i;j++)
printf("text[%d]=%s",j,text[j]);
Another method would be to manually copy each character until a space is seen.
int len=strlen(line);
int i=0;
int k=0;
for(int j=0;j<len+1;j++)
{
if(line[j]==' ')
{
text[i][k]='\0';
i++;
k=0;
}
else
{
text[i][k]=line[j];
k++;
}
}
Note that the above code does not prevent buffer overflows. You can print each word using
for(int j=0;j<i+1;j++)
printf("text[%d]=%s",j,text[j]);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
char string[100];
fgets(string, 100, stdin);
string[strlen(string)-1] = 0;
// create an array of pointers
char **string_array = (char**)malloc(sizeof(char*));
int i = 0, array_size;
// tokenize input
char *token = strtok(string, " ");
while(token!=NULL) {
// dynamically increase the array during run time
string_array = (char**)realloc(string_array, (i+1)*sizeof(char**));
// create the string as you would do when there is only one string
string_array[i] = (char*)malloc(strlen(token)+1);
strcpy(string_array[i], token);
token = strtok(NULL, " ");
i++;
}
array_size = i;
for(i=0; i<array_size; i++) {
printf("%s\n", string_array[i]);
}
return 0;
}
Basically you create an array of pointers and you allot memory for the strings one by one as you would do when there is only one string.
(if number of token is unknown, use realloc to increase the size of pointer to pointers.)
#include <stdio.h>
#include <ctype.h>
int main(void){
char line[300] = "hello world bye bye\n";
char temptext[100][15]={0};
int i=0, j, k=0;
while(line[k]){
if(isspace(line[k])){
++k;//skip space to word
continue;
}
for(j=0; j < 15-1 && line[k] && !isspace(line[k]); ++k, ++j)
temptext[i][j] = line[k];
if(j && ++i == 100)
break;
}
for(j=0; j<i; ++j)
puts(temptext[j]);
return 0;
}
#include<stdio.h>
#define NEWLINE printf("\n")
int main(void)
{
char string[]="hello world bye bye";
int index=0;
while(string[index])
{
if(string[index]==32)
{
NEWLINE;
index++;
}
else
{
printf("%c",string[index]);
index++;
}
}
NEWLINE;
}
// Whenever i encountered with a space, i am printing a new line on the screen. Here 32 is the ASCII value for space

Resources