Currently struggling to solve ex 1.21. The task is: Write a program entab that replaces strings of blanks by the minimum number
of tabs and blanks to achieve the same spacing. Use the same tab stops as for detab . When
either a tab or a single blank would suffice to reach a tab stop, which should be given
preference?
Below is my code i have made so far. I have no problems typing the amount of spaces less than tabsize but when it is bigger than that I get segmentation fault. Could anyone help me, please?
#include <stdio.h>
#include <ctype.h>
#define TAB 8
#define MAXLINE 1000
int getmine(char s[], int lim);
int entab(char output[], int pos, int space);
int main()
{
char line[MAXLINE], output[MAXLINE];
int i;
while ((i = getmine(line, MAXLINE)) > 0)
{
int space = 0;
int pos = 0;
int count = 0;
while (line[count] != '\n')
{
if (line[count] != ' ')
{
space = 0;
output[count] = line[count];
}
else if (line[count] == ' ')
{
pos = count - space;
space++;
if (line[count + 1] != ' ')
{
if (space > TAB)
{
int z = entab(output, pos, space);
count = z;
}
else
{
for (int a = 0; a < space; a++)
output[pos + a] = ' ';
}
}
}
count++;
}
if (line[count] == '\n')
{
output[count] = line[count];
count++;
}
output[count] = '\0';
printf("%s", output);
}
}
int getmine(char s[],int lim)
{
int c, i;
for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
if (c == '\n')
{
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
int entab(char output[], int pos, int space)
{
int nTabs = 0;
int nSpaces = 0;
int x = TAB - (pos % TAB);
if (x > 0)
{
output[pos] = '\t';
space = space - x;
nTabs = space / TAB;
nSpaces = space % TAB;
for (int a = 0; a < nTabs; a++)
output[pos + 1 + a] = '\t';
for (int b = 0; b < nSpaces; b++)
output[pos + 1 + nTabs + b] = ' ';
return pos + nTabs + nSpaces + 1;
}
else if (x == 0)
{
nTabs = space / TAB;
nSpaces = space % TAB;
for (int a = 0; a < nTabs; a++)
output[pos + a] = '\t';
for (int b = 0; b < nSpaces; b++)
output[pos + nTabs + b] = ' ';
return pos + nTabs + nSpaces;
}
}
Because the whitespace sequences of 8 characters are replaced by a single character (the tab), the number of read bytes from the input do not match to the written bytes in the output. A simple solution for this, is to simply keep track of two variables, one for the read bytes from the input, and one for the written bytes to the output. You could do this somewhat neater with pointers, though if you are following the book in a linear fashion, IIRC pointers are introduced later on.
Untested (namely for demonstrative purposes) code below.
NOTE: I took some liberties in reformatting your code for brevity.
#include <stdio.h>
#include <ctype.h>
#define TAB 8
#define MAXLINE 1000
int getmine(char s[], int lim);
int entab(char output[], int pos, int space);
int main()
{
char line[MAXLINE], output[MAXLINE];
int i;
while ((i = getmine(line, MAXLINE)) > 0) {
int space = 0;
int pos = 0;
int read_bytes = 0;
int write_bytes = 0;
while(read_bytes < i) {
if (line[read_bytes] != ' ') {
space = 0;
output[write_bytes++] = line[read_bytes];
}
else if (line[read_bytes] == ' ') {
space++;
if (line[read_bytes + 1] != ' ') {
if (space > TAB) {
write_bytes += entab(output, write_bytes, space);
} else {
for (int i = 0; i < space; i++)
output[write_bytes++] = ' ';
}
}
}
read_bytes++;
}
if (line[read_bytes] == '\n') {
output[write_bytes++] = line[read_bytes];
}
output[write_bytes] = '\0';
printf("%s", output);
}
}
int getmine(char s[],int lim)
{
int c, i;
for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
int entab(char output[], int pos, int space)
{
int nTabs = 0;
int nSpaces = 0;
int x = TAB - (pos % TAB);
if (x > 0) {
output[pos] = '\t';
space = space - x;
nTabs = space / TAB;
nSpaces = space % TAB;
for (int i = 0; i < nTabs; i++)
output[pos + 1 + i] = '\t';
for (int i = 0; i < nSpaces; i++)
output[pos + 1 + nTabs + i] = ' ';
return nTabs + nSpaces + 1;
} else if (x == 0) {
nTabs = space / TAB;
nSpaces = space % TAB;
for (int i = 0; i < nTabs; i++)
output[pos + i] = '\t';
for (int i = 0; i < nSpaces; i++)
output[pos + nTabs + i] = ' ';
}
return nTabs + nSpaces;
}
In my solution I used external variables for index counter of output line.
And I made separated function for converting input array to output array.
#include <stdio.h>
#define TAB 8
#define MAX 100;
int j; //counter of newline
char line[MAX];
char newline[MAX];
int getter(void);
void converter(void);
int entab(int space_counter, int line_index);
int main()
{
extern char line[];
extern char newline[];
int len;
while ((len = getter()) > 0) {
converter();
printf("%s", newline);
}
}
int getter()
{
int c;
int i;
i = 0;
while ((c = getchar()) != EOF && c != '\n' && i < 30-1) {
line[i] = c;
++i;
}
if (c == '\n') {
line[i] = c;
++i;
}
line[i] = '\0';
return i;
}
void converter(void)
{
extern int j;
extern char line[];
extern char newline[];
int space_counter;
int i;
i = j = 0;
space_counter = 0;
while (line[i] != '\0') {
while (line[i] == ' ') {
space_counter++;
i++;
}
if (space_counter > 0) {
j = entab(space_counter, i);
space_counter = 0;
}
else {
newline[j] = line[i];
j++;
i++;
}
}
newline[j] = '\0';
}
int entab(int space_counter, int end_point)
{
extern int j;
extern char newline[];
int new_index;
int start_point;
int tab_qty;
int space_qty;
start_point = end_point - space_counter;
tab_qty = end_point / TAB - start_point / TAB;
if (TAB > start_point)
space_qty = space_counter;
else
space_qty = end_point % TAB;
for (tab_qty; tab_qty > 0; tab_qty--) {
newline[j] = '\t';
j++;
}
for (space_qty; space_qty > 0; space_qty--) {
newline[j] = '|';
j++;
}
return new_index = j;
}
Related
Write a function that takes a string as a parameter and returns its words sorted in order of their length first and then in alphabetical order on line separated by '^'
here is examples of output
There will be only spaces, tabs and alphanumeric caracters in strings.
You'll have only one space between same size words and ^ otherwise.
A word is a section of string delimited by spaces/tabs or the start/end of the string. If a word has a single letter, it must be capitalized.
A letter is a character in the set [a-zA-Z]
here is my code, but it returns nothing I think issue in last function....
#include <unistd.h>
#include <stdlib.h>
int is_upper(char c)
{
return c >= 'A' && c <= 'Z';
}
int my_lower(char c)
{
if (is_upper(c))
return c + 32;
return c;
}
int my_strlen(char *s)
{
int i = 0;
for (; s[i]; i++)
;
return i;
}
int my_is(char c)
{
return c == ' ' || c == '\t';
}
char *my_strsub(char *s, int start, int end)
{
char *res = malloc(end - start);
int i = 0;
while (start < end)
res[i++] = s[start++];
res[i] = 0;
return res;
}
int cmp_alpha(char *a, char *b)
{
while (*a && *b && *a == *b)
{
a++;
b++;
}
return my_lower(*a) <= my_lower(*b);
}
int cmp_len(char *a, char *b)
{
return my_strlen(a) <= my_strlen(b);
}
void my_sort(char *arr[], int n, int(*cmp)(char*, char*))
{
char *tmp;
for (int i = 0; i < n; i++)
for (int j = 0; j < n - 1; j++)
{
if ((*cmp)(arr[j], arr[j + 1]) == 0)
{
tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
char* long(char *s)
{
int start = 0, idx = 0;
char *words[my_strlen(s) / 2 + 1];
for (int i = 0; s[i]; i++)
{
if (!my_is(s[i]) && i > 0 && my_is(s[i - 1]))
start = i;
if (my_is(s[i]) && i > 0 && !my_is(s[i - 1]))
words[idx++] = my_strsub(s, start, i);
if (!s[i + 1] && !my_is(s[i]))
words[idx++] = my_strsub(s, start, i + 1);
}
my_sort(words, idx, &cmp_alpha);
my_sort(words, idx, &cmp_len);
char* res = malloc(100);
int pushed=0;
for (int i = 0; i < idx - 1; i++)
{
res[pushed]=*words[i];
if (my_strlen(&res[pushed]) < my_strlen(&res[pushed + 1]))
{
res[pushed]=res[94];
}
else
{
res[pushed]=res[32];
}
pushed++;
}
res[pushed]='\0';
return res;
}
int main()
{
long("Never take a gamble you are not prepared to lose");
return 0;
}
Apart from the off-by-one allocation error in my_strsub, separating and sorting the words seems to work well. Only then you confuse the result character array with a character pointer array, e. g. with res[pushed]=*words[i] you write only the first character of a word to the result. The last for loop of ord_alphlong could rather be:
if (idx)
for (int i = 0; ; )
{
char *word = words[i];
int lng = my_strlen(word);
if (100 < pushed+lng+1) exit(1); // too long
for (int i = 0; i < lng; ) res[pushed++] = word[i++];
if (++i == idx) break; // last word
res[pushed++] = lng < my_strlen(words[i]) ? '^' // other size
: ' '; // same size
}
Of course in order to see the result of the function, you'd have to output it somehow.
I would like to fit a string into multiple rows of a fixed width. I managed to separate the string into different rows so that their length will not pass the fixed width, but the problem is that some rows are not width (80) characters long, this is why I am trying to distribute the extra_space by adding spaces between words.
#include <stdio.h>
#include <string.h>
#include "stringdefault.h"
#include <conio.h>
#include <stdlib.h>
int main(){
int width = 80;
char s1[10000];
char substring[100] = " ";
char space = ' ';
gets(s1);
removeSpaces(s1);
char *base,*right_margin;
int extraSpace, numWords, numSpaces, incrementEachSpaceby, ind1, ind2, k;
int length;
length = string_length(s1);
base = s1;
for(int i = 0; i < width; i++)
{
printf("%d", i%10);
}
printf("\n");
while(*base)
{
if(length <= width)
{
puts(base); // display string
return(0); //and leave
}
right_margin = base+width;
while(!isspace(*right_margin))
{
right_margin--;
if( right_margin == base)
{
right_margin += width;
while(!isspace(*right_margin))
{
if( *right_margin == '\0')
break;
right_margin++;
}
}
}
*right_margin = '\0';
if(string_length(base) < width)
{
char *newStr = malloc(width);
extraSpace = width - string_length(base);
numWords = numberOfWords(base);
numSpaces = numWords - 1;
incrementEachSpaceby = extraSpace/numSpaces;
ind1 = 0;
ind2 = 0;
while (ind2 < width)
{
newStr[ind2] = base[ind1];
ind1++;
ind2++;
}
for(int i = 0; newStr[i]!='\0'; i++)
if((isspace(newStr[i])))
{
if(extraSpace > 0)
k = extraSpace;
else
k = 1;
while(k)
{
insert_substring(newStr, substring, i);
k--;
}
}
puts(newStr);
}
else
puts(base);
length -= right_margin-base+1; // +1 for the space
base = right_margin+1;
}
return 0;
}
stringdefault.h
int string_length(char s[])
{
int length = 0;
for(int i=0; s[i]!='\0'; i++)
length++;
return length;
}
char *substring(char *string, int position, int length)
{
char *pointer;
int c;
pointer = malloc(length+1);
if( pointer == NULL )
exit(EXIT_FAILURE);
for( c = 0 ; c < length ; c++ )
*(pointer+c) = *((string+position-1)+c);
*(pointer+c) = '\0';
return pointer;
}
void insert_substring(char *a, char *b, int position)
{
char *f, *e;
int length;
length = strlen(a);
f = substring(a, 1, position - 1 );
e = substring(a, position, length-position+1);
strcpy(a, "");
strcat(a, f);
free(f);
strcat(a, b);
strcat(a, e);
free(e);
}
char *removeSpaces(char *str)
{
int ip_ind = 0;
char *ptr;
while(*(str + ip_ind))
{
if ( (*(str + ip_ind) == *(str + ip_ind + 1)) && (*(str + ip_ind)==' ') )
{
ptr = str + ip_ind+1;
do{
*(ptr-1) = *ptr;
}while(*ptr++ != '\0');
}
else
ip_ind++;
}
*(str + ip_ind) = '\0';
return str;
}
The output that I get without the while loop inside the if statement
It seems that the newStr set of characters, contains spaces before it's first character.
I have this code, what i want it to do is print the string that represents the word, and print the number of times it occurred in the file, instead it outprints something liek this: (a load of blank space) and then this number -1076720020, which i have no idea where it came from, how would i go about fixing this?
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
struct podatki {
char beseda[1000];
int frekvenca;
};
void zamenjaj(char *str1, char *str2) {
char *beseda2 = (char *)malloc((strlen(str1) + 1) * sizeof(char));
strcpy(beseda2, str1);
strcpy(str1, str2);
strcpy(str2, beseda2);
free(beseda2);
}
int posodobi(struct podatki s[], const char unit[], int count) {
int i =0;
for (i = 0; i < count; i++) {
if (strcmp(s[i].beseda, unit) == 0) {
s[i].frekvenca++;
return count;
}
}
strcpy(s[count].beseda, unit);
s[count].frekvenca++;
return (count + 1);
}
int main() {
int stBes;
scanf("%d", &stBes);
//zacetne deklaracije
struct podatki s[1000];
char string[1000], unit[2000], c;
int i = 0;
int frekvenca = 0;
int j = 0;
int count = 0;
int num = 0;
//branje
for (i = 0; i < 1000; i++) {
s[i].frekvenca = 0;
}
i = 0;
do {
fflush(stdin);
c = getchar();
string[i++] = c;
} while (c != '\n');
//pretvori v majhne crke
char *p;
for (p = string; *p != '\0'; ++p) {
*p = tolower(*p);
}
string[i - 1] = '\0';
for (i = 0; i < strlen(string); i++) {
while (i < strlen(string) && string[i] != ' ' && !ispunct(string[i])) {
unit[j++] = string[i++];
}
if (j != 0) {
unit[j] = '\0';
count = posodobi(s, unit, count);
j = 0;
}
}
int a;
for (i = 0; i < count; ++i) {
for (j = i + 1; j < count; ++j) {
if (s[i].frekvenca < s[j].frekvenca) {
a = s[i].frekvenca;
s[i].frekvenca = s[j].frekvenca;
s[j].frekvenca = a;
zamenjaj(s[i].beseda, s[j].beseda);
}
}
}
for (i = 0; i < count; i++) {
for (j = 1; j < count; j++) {
if (s[i].frekvenca == s[j].frekvenca){
if (strcmp(s[i].beseda, s[j].beseda) < 0) {
a = s[i].frekvenca;
s[i].frekvenca = s[j].frekvenca;
s[j].frekvenca = a;
zamenjaj(s[i].beseda, s[j].beseda);
}
}
}
}
//printanje
for (i = 0; i < stBes; i++) {
printf("%s\t %d\n", s[i].beseda, s[i].beseda);
if (s[i].frekvenca > 1) {
num++;
}
}
return 0;
}
The problem is that you convert the string to lower case before nul terminating it.
Here
i = 0;
do {
fflush(stdin);
c = getchar();
string[i++] = c;
} while (c != '\n');
/* Goes here <---------------------+ */
/* | */
//pretvori v majhne crke | */
char *p; /* | */
for (p = string; *p != '\0'; ++p) {/* | */
*p = tolower(*p);/* | */
} /* | */
/* | */
string[i - 1] = '\0'; /* ---------------------+ */
You should also remove the fflush(stdin) and instead use getchar() to fetch the white space characters ignored by the previous scanf(), and please use scanf() correctly and check it's returned value.
It is sufficient to say that I am new to C so please have show some mercy ;).
I'm trying to compare two strings. The output shouldn't contain common characters. Sadly it does.
Here is the code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
const char msg[15] = "blueberry";
int c;
int s[15];
int j = 0;
int i = 0;
int k= 0;
int ok = 0;
int t = 0;
while (i < 15 && (c = getchar()) != '\n')
{
s[i] = c;
++i;
}
for (t=j=0; t < 15; ++t)
{
ok = 1;
//printf ("%c", s[t]);
}
for (k=0; msg[k] != '\0'; ++k)
{
if (s[t] == msg[k])
{
ok = 0;
}
}
if (ok == 1)
{
s[j] = s[t];
j++;
}
s[j] = '\0';
for (j = 0; j < 15; ++j)
printf ("%c ", s[j]);
}
The input from the keyboard is blackberry, expected output should've been U but sadly it is not. Any help please. Also why is it entering the nested for loop irrespective of condition?
My big thanks to everyone, it helped me a lot. I've figured out a way & am ok with the output. I've borrowed some ideas from A4L :).
To compare two string, you can use strcmp().
The following is a string compare program that you can use for your reference. I has both array and pointer version for better understanding.
#include <stdio.h>
int strcmp1(char a[], char b[])
{
int i=0;
while (a[i] == b[i]) {
if (a[i] == '\0')
return 0;
i++;
}
return a[i]-b[i];
}
int strcmp2(char *a, char *b)
{
while (*a == *b) {
if (*a == '\0')
return 0;
a++; b++;
}
return *a-*b;
}
int main()
{
char s1[] = "test string1";
char s2[] = "test string";
char s3[] = "aaa";
char s4[] = "bbb";
printf("strcmp1(%s, %s) = %d \n", s1, s2, strcmp1(s1, s2));
printf("strcmp2(%s, %s) = %d \n", s3, s4, strcmp2(s3, s4));
return 0;
}
given that msg contains "blueberry" and s contains "blackberry" this should do it
for (int i=0; i < strlen(msg); i++) {
for (int j = 0; j < strlen(s); j++) {
if (msg[i] != s[j]) {
printf ("%c", msg[i]);
}
}
}
yes it's ugly (using the strlen in the for gives me the chills, but I'm still low on coffeine today ^^)
i guess you want to find the first letter where the input differs from message
here is your own code with some fixes
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char msg[15] = "blueberry";
int c;
char s[15];
int i = 0;
int k= 0;
int ok = 0;
while (i < 15 && (c = getchar()) != '\n')
{
s[i] = (char) c;
++i;
}
// make sure to terminate the string after hitting enter
s[i] = '\0';
printf("input: %s\n", s);
printf("messg: %s\n", msg);
// run through both input and message with one counter
for (k=0; ok == 0 && msg[k] != '\0' && s[k] != '\0'; )
{
// if different chars stop
if (s[k] != msg[k]){
ok = 1;
} else {
// next char
k++;
}
}
if (ok == 1)
{
printf ("diff # index %d -> %c\n", k, msg[k]);
}
else
{
printf ("no diff\n");
}
return 0;
}
#include <stdio.h>
#include <string.h>
//Length to match
int comm(char* s1, char* s2){
int len = 0;
while(*s1 && *s2 && *s1++ == *s2++)
++len;
return len;
}
//commdiffcomm
/*
int commr(char* s1, char* s2){
int len = 0, limit;
int len1,len2;
len1 = strlen(s1);
len2 = strlen(s2);
limit = len1 > len2 ? len2 : len1;
s1 = s1 + len1;
s2 = s2 + len2;
while(limit-- && *--s1 == *--s2)
++len;
return len;
}
//bad
int diff(char* s1, char* s2, int* len1, int* len2){
int len, lenr, s1_len, s2_len, wk_max, i, j;
len = comm(s1, s2);
if(strcmp(s1, s2)==0){
*len1 = *len2 = 0;
return len;
}
lenr = commr(s1, s2);
*len1 = strlen(s1) - len - lenr;
*len2 = strlen(s2) - len - lenr;
return len;
}
*/
int diff(char* s1, char* s2, int* len1, int* len2){
int len, s1_len, s2_len, wk_max, i, j;
len = comm(s1, s2);
if(strcmp(s1, s2)==0){
*len1 = *len2 = 0;
return len;
}
s1_len = strlen(s1 + len + 1);
s2_len = strlen(s2 + len);
wk_max = 0;
for(i = 1; i < s1_len ; i++){
for(j = 0; j < s2_len; j++){
int com_len;
com_len = comm(s1 + len + i, s2 + len + j);
if(wk_max < com_len){
wk_max = com_len;
*len1 = i;
*len2 = j;
}
}
}
return len;
}
int main(){
char str1[16] = "blueberry";
char str2[16] = "blackberry";
char dif1[16] = "";
char dif2[16] = "";
int len0;//length of top to diff pos
int len1;
int len2;
len0 = diff(str1, str2, &len1, &len2);
strncpy(dif1, str1 + len0, len1);
strncpy(dif2, str2 + len0, len2);
if(len1 !=0 && len2 != 0){
printf("%s different %s at position %d length %d (\"%s\")\n", str1, str2, len0, len1, dif1);
printf("%s different %s at position %d length %d (\"%s\")\n", str2, str1, len0, len2, dif2);
} else {
printf("two string is same.");
}
return 0;
}
/*
blueberry different blackberry at position 2 length 2 ("ue")
blackberry different blueberry at position 2 length 3 ("ack")
*/
There are a few problems with the code as is:
You don't null-terminate your input string. Attempting to use it with c string functons would spell trouble. To fix that, change
while (i < 15 && (c = getchar()) != '\n')
{
s[i] = c;
++i;
}
to
while (i < 14 && (c = getchar()) != '\n')
{
s[i] = c;
++i;
}
s[i] = '\0';
Your specification is unclear as to whether you want your program to print the letters unique to msg, or to both s and msg. (i.e, do you want msg-s or (msg ∪ s)-(msg ∩ s) Assuming the first, the important part of your program goes like this:
k=0;
for(i=0;i<strlen(msg);i++){
int exists = 0;
for(j=0;!exists && j<strlen(s);j++){
if(msg[j] == s[i])
exists = 1;
}
if(!exists)
msg[k++] = msg[i];
}
s[k] = '\0';
The inner loop checks if s contains the current character in msg. If it does, we don't do anything, but if it doesn't, we append it to the end of a sublist we're creating on top of the bits of msg we've already processed.
your code is a mess even after the rewrite - there are too many errors to describe in detail
/*
blackbery
b l u e b e r r y
. . a c k b e . .
result = non-equal
*/
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char msg[15] = "blueberry";
int c, s[15], i,j,k, ok;
for (i=0; i < 15; i++) s[i] = 0;
for (i=0; i < 15 && (c = getchar()) != '\n'; i++) s[i] = c;
for (ok=1, k=0; msg[k] != '\0'; ++k)
if (s[k] != msg[k]) ok = 0; else s[k] = '.';
for (j = 0; j < 15; ++j) printf ("%c ", msg[j]);
printf("\n");
for (j = 0; j < 15; ++j) printf ("%c ", s[j]);
printf("\nresult = %s\n", ok ? "equal" : "non-equal");
}
This code must naturally sort an array of strings and it gives a segfault. Unfortunately, I don't know what input it gives segfault on, but I suppose that segfault occurs when allocating memory for strings. Maximum string length is 9000000.
Here it is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void
strsort(char **string, int left, int right) {
char *comp, *temp;
int i, j, p;
while(left < right) {
i = left;
j = right;
p = (left + right) / 2;
comp = string[p];
while(1) {
while(i <= j && strcmp(string[i], comp) <= 0)
i++;
while(i <= j && strcmp(string[j], comp) > 0)
j--;
if(i > j)
break;
temp = string[i];
string[i] = string[j];
string[j] = temp;
if(j == p)
p = i;
i++; j--;
}
string[p] = string[j];
string[j] = comp;
j--;
if((j - left) < (right - i)) {
strsort(string, left, j);
left = i;
} else {
strsort(string, i, right);
right = j;
}
}
}
void
ignore_line(void) {
char c;
while((c = getchar()) != '\n');
}
int
main(void) {
enum
{
L = 9000001
};
int n, i, j, len;
char offset = 'a' - 'A';
scanf("%d", &n); ignore_line();
char **string = (char **)malloc(n * sizeof(char *));
for(i = 0; i < n; ++i) {
string[i] = (char *)malloc(L * sizeof(char));
len = -1;
while((string[i][++len] = getchar()) != '\n') {
if(string[i][len] >= 'a')
string[i][len] -= offset;
else
string[i][len] += offset;
}
string[i] = (char *)realloc(string[i], len + 1);
string[i][len] = '\0';
}
strsort(string, 0, n - 1);
for(i = 0; i < n; ++i) {
j = 0;
while(string[i][j] != '\0') {
if(string[i][j] >= 'a')
printf("%c", string[i][j] - offset);
else
printf("%c", string[i][j] + offset);
++j;
}
printf("\n");
}
return 0;
}
The first seg fault is thrown at:
while(i <= j && strcmp(string[i], comp) <= 0)
Consider simply sending a char* to strsort, instead of char**, and comparing instances of char. Much of your code is overcomplicated.
void
strsort(char* string, int left, int right) {
char comp, temp;
See my quicksort implementation.