I am trying to solve a question on codechef. This code is running fine as far as logic is considered, but I am having trouble with giving large inputs.
For example, if I give input of 13 or more digits then it does not run in vscode, and if the input is 22 digits or more then it does not run in devc++.
#include <stdio.h>
#include <math.h>
#include<string.h>
int main() {
int t, l, i, flag = 0;
char ch = ' ';
scanf("%d", &t);
char d[t][100000];
int out[t];
for(i = 0; i < t; i++) {
scanf("%s", &d[t]);
size_t len = strlen(d[t]);
printf("\n%d", len);
char ch = d[t][0];
for (size_t j = 0; j < len; j++) {
if ((ch != d[t][j])) {
flag++;
}
}
if (flag >= 2 && flag != (len-1))
out[i]=0;
else
out[i]=1;
flag = 0;
}
for(i = 0; i < t; i++) {
if (out[i] == 1)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
TEST RUN 1:-
1
11110111111
11
Yes
TEST RUN 2:-
1
111101111111
0
Why doesn't it handle larger inputs?
When you start writing from d[t], you are out of the bounds of the array, meaning that you might be overwriting other parts of your program. You should instead write to d[i].
Also this array is now on the stack, but the stack only has a very limited size, so there is a high risk you might go over that size, which is called a stack overflow. On windows the stack size is I think 1MB, so if t was bigger than 10 you would already exceed that. So you should allocate on the heap instead.
This should work, but I did not test it:
int t = 0;
scanf("%d", &t);
char **d = (char **)malloc(t * sizeof(char *));
for (int i = 0; i < t; i++){
d[i] = (char *)malloc(STR_SIZE * sizeof(char));
scanf("%s", d[i]);
}
Related
I'm writing an implementation of the Moore Voting algorithm for finding the majority element (i.e. the element which occurs more than size/2 times) in an array. The code should return the majority element if it exists or else it should return -1. Now my version of the majorityElement(int size, int arr[]) seems to work perfectly fine if I directly hardcode the integer array in the main() function and invoke it from there.
int majorityElement(int size, int arr[])
{
int majorityindex = 0;
int votes = 1;
int index;
for (index = 1; index < size; index++)
{
if (arr[index] == arr[majorityindex])
votes++;
else
votes--;
if (votes == 0)
{
majorityindex = index;
votes = 1;
}
}
int count = 0;
int i;
for (i = 0; i < size; i++)
{
if(arr[majorityindex] == arr[i])
count++;
}
if (count > (size/2))
return arr[majorityindex];
return -1;
}
However, I'm facing some issues if I try to read an input stream like these:
2
5
3 1 3 3 2
3
1 2 3
The first line of the input contains the number of test cases. The first line of the test case will be the size of the array and the second line will be the elements of the array.
I tried to read the input stream from within the main() function like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
int majorityElement(int size, int arr[]);
int main()
{
char buf[3];
fgets(buf, MAX, stdin);
int n = atoi(buf);
char a[3];
char b[MAX];
int i;
int count;
int* num;
for (i = 0; i < n; i++)
{
count = 0;
fgets(a, MAX, stdin);
fgets(b, MAX, stdin);
int x = atoi(a);
char* num[x];
int arr[x];
int k = 0;
char* token = strtok(b, " ");
while (token != NULL)
{
num[k] = token;
arr[k] = atoi(num[k]);
token = strtok(NULL, " ");
k++;
}
printf("%d\n", majorityElement(x, arr));
}
return 1;
}
I took the size of buf[] and a[] as 3 during declaration as they must have sufficient space for the \n character read by fgets() as well as the terminating \0 character. As far as I know, the atoi() function ignores the \n character while converting the character array (string) into an integer. I tried to store the first entry of the input (i.e. the number of entries) in a character array buf, converted it into a string and stored it in a variable n. Similarly, I tried to obtain the size of a test array in a variable x and the test arrays (second line of test case) in an integer array arr. While buf and n seem to obtain the correct values in all cases, I'm not quite sure about arr. I'm aware that fgets() leaves a terminal \n character and that might be causing some havoc during tokenization using strtok, although I can't finger at why. I tried submitting this code on GeeksForGeeks. It gives absolutely correct outputs for the sample test case:
2
5
3 1 3 3 2
3
1 2 3
that is
3
-1
However, when I try to "submit" my solution it says:
Possibly your code doesn't work correctly for multiple test-cases (TCs).
The first test case where your code failed:
Input:
4
1 2 2 1
Its Correct output is:
-1
And Your Code's output is:
1
I can't seem to make sense of this. If I manually write this in stdin:
1
4
1 2 2 1
the code outputs
-1
which is indeed the correct solution. This doesn't match with the output claimed during the submission i.e. 1. So I'm not really sure where I'm going wrong. Have I used fgets() or strtok() incorrectly in the main() function? Or is it something else?
Updated the main() function according to suggestions in the comments.
int main()
{
char buf[MAX];
fgets(buf, MAX, stdin);
int n = atoi(buf);
char a[MAX];
char b[MAX];
int i;
int count;
int* num;
for (i = 0; i < n; i++)
{
count = 0;
fgets(a, MAX, stdin);
fgets(b, sizeof(a), stdin);
a[sizeof(a)-1] = '\0';
b[sizeof(b)-1] = '\0';
int x = atoi(a);
int arr[x];
int k = 0;
char* token = strtok(b, " ");
while (token != NULL)
{
if (k > x)
break;
arr[k] = atoi(token);
token = strtok(NULL, " ");
k++;
}
printf("%d\n", majorityElement(x, arr));
}
return 1;
}
As pointed out by #Vlad, the MAX was set too low in my original array. The question says that the number of entries in an array is upper bounded by 10^7 and each array entry is upper bounded by 10^6 (7 digits). So MAX needs to be of the order 10^8. According to the suggestions in the comments, I'm now using dynamic allocation instead of variable length arrays.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 10000000
int majorityElement(int size, int arr[])
{
int majorityindex = 0;
int votes = 1;
int index;
for (index = 1; index < size; index++)
{
if (arr[index] == arr[majorityindex])
votes++;
else
votes--;
if (votes == 0)
{
majorityindex = index;
votes = 1;
}
}
int count = 0;
int i;
for (i = 0; i < size; i++)
{
if(arr[majorityindex] == arr[i])
count++;
}
if (count > (size/2))
return arr[majorityindex];
return -1;
}
int main()
{
char* buf = calloc (MAX, sizeof(char));
fgets(buf, MAX, stdin);
int n = atoi(buf);
char* a = calloc (MAX, sizeof(char));
char* b = calloc(MAX, sizeof(char));
int i;
for (i = 0; i < n; i++)
{
fgets(a, MAX, stdin);
fgets(b, MAX, stdin);
a[strlen(a)-1] = '\0';
b[strlen(b)-1] = '\0';
int x = atoi(a);
int *arr = calloc(x, sizeof(int));
int k = 0;
char* token = strtok(b, " ");
while (token != NULL)
{
if (k > x)
break;
arr[k] = atoi(token);
token = strtok(NULL, " ");
k++;
}
printf("%d\n", majorityElement(x, arr));
free(arr)
}
free(buf);
free(a);
free(b);
return 1;
}
If I set MAX to 10^7 then the code passes all the test cases and is accepted for submission. However, if I set MAX to 10^8 (as required), I get a segmentation fault. How to overcome this?
Your program has several drawbacks.
For example within the function main there are unused variables declared like
int count;
int* num;
The function does take into account that -1 can be a valid value of the array.
There is a problem with the number of elements that can be specified in a test. It is a very big number (according to the description 1 <= N <= 10000000). So the value of MAX equal to 100 is too low. As a result the data can be read incorrectly and not completely. Also there can occur problems with the variable length arrays.
There is no need to use the function fgets because each integer number can be read using scanf.
I could suggest the following solution. Try it and see whether it will pass the tests.
#include <stdio.h>
#include <stdlib.h>
size_t majorityElement( const int a[], size_t n )
{
size_t majority_index = 0;
for ( size_t i = 1, votes = 1; i < n; i++ )
{
if ( a[majority_index] == a[i] )
{
++votes;
}
else
{
--votes;
}
if ( votes == 0 )
{
majority_index = i;
++votes;
}
}
size_t count = 0;
for ( size_t i = 0; i < n; i++ ) count += a[i] == a[majority_index];
return n / 2 < count ? majority_index : n;
}
int main(void)
{
size_t n = 0;
scanf( "%zu", &n );
for ( size_t i = 0; i < n; i++ )
{
size_t m = 0;
scanf( "%zu", &m );
if ( m != 0 )
{
int *a = calloc( m, sizeof( int ) );
for ( size_t j = 0; j < m; j++ ) scanf( "%d", a + j );
size_t majority_index = majorityElement( a, m );
printf( "%d\n", majority_index == m ? -1 : a[majority_index] );
free( a );
}
}
return 0;
}
If it will not pass the tests then it seems there is a bug in tests.:)
Or if the function return type may not be changed then the function definition can look like
int majorityElement( const int a[], size_t n )
{
size_t majority_index = 0;
for ( size_t i = 1, votes = 1; i < n; i++ )
{
if ( a[majority_index] == a[i] )
{
++votes;
}
else
{
--votes;
}
if ( votes == 0 )
{
majority_index = i;
++votes;
}
}
size_t count = 0;
for ( size_t i = 0; i < n; i++ ) count += a[i] == a[majority_index];
return n / 2 < count ? a[majority_index] : -1;
}
I got a problem of completing the code below.
#include <stdio.h>
void triR(void)
{
int size, repeat;
scanf("%d %d", &size, &repeat);
printf("Hello world\n");
// ...
// Complete this function
// ...
printf("Bye world\n");
}
Example of function excution
The above three are the input values.
I think The first is the minimum size of the number (I do not know why it does not work if I do not enter 1), the middle is the maximum size of the number, and the last is the number of iterations of the input value.
After looking at the example, I created the following code
#include <stdio.h>
#include <stdlib.h>
void triR(void)
{
int size, repeat;
int num;
scanf("%d %d", &size, &repeat);
printf("Hello world\n");
for (int b = 0; b < size; ++b) //b = horizontal line, a = number
{
for (int a = 0; a <= b; ++a)
{
for (num = 1; num <= a; ++num) - failed sentences
{
printf("%d", num);
}
}
printf("\n");
}
for (int k = size; k > 0 ; --k) //k = horizontal line, i = number
{
for (int i = 1; i < k; ++i)
{
{
printf("*"); -Sentences that were successfully run using *
}
}
printf("n");
}
// for (int c =o; ) - sentences tried to make about repeating output value
printf("Bye world\n");
return 0;
}
I know my code looks a lot strange.
I didn't have the confidence to make that code in numbers, so I tried to make it * and convert it.
It succeeded in running by *, but it continues to fail in the part to execute by number.
There is no one to ask for help, but I am afraid that I will not be able to solve it even if I am alone in the weekend. I can not even convert numbers far repeated outputs. I would really appreciate it even if you could give me a hint.
The above code I created(Failed)
Code with *
I'd like to say that even though I managed an implementation, it is definitely neither efficient nor practical. I had to restrict your size variable to digits, as I used ASCII to convert the numbers into characters and couldn't use the itoa() function, since it's not standard.
#include <stdio.h>
#include <stdlib.h>
void triR(void) {
int size, repeat;
scanf("%d %d", &size,&repeat);
printf("Hello world\n");
// string size of n^2+2n-1
char* print_string = malloc((size*size+2*size-1)*sizeof(char));
unsigned int number = 1;
unsigned int incrementer = 1;
while (number < size) {
for (int i = 0; i < number; i++) {
*(print_string+i+incrementer-1) = 48+number;
}
incrementer+=number;
number++;
*(print_string+incrementer-1) = '\n';
incrementer++;
}
while (number > 0) {
for (int i = 0; i < number; i++) {
*(print_string+i+incrementer-1) = 48+number;
}
incrementer+=number;
number--;
*(print_string+incrementer-1) = '\n';
incrementer++;
}
for (int i = 0; i < repeat; i++) {
printf("%s\n", print_string);
}
printf("Bye world\n");
free(print_string);
}
I allocated a char* with the size of size^2+2size-1, as this is the size required for the newline and number characters.
The variables number and incrementer are unsigned and start at 1 as they don't need to go below 1.
I put two while loops with similar code blocks in them:
while (number < size) {
for (int i = 0; i < number; i++) {
*(print_string+i+incrementer-1) = 48+number;
}
incrementer+=number;
number++;
*(print_string+incrementer-1) = '\n';
incrementer++;
}
while (number > 0) {
for (int i = 0; i < number; i++) {
*(print_string+i+incrementer-1) = 48+number;
}
incrementer+=number;
number--;
*(print_string+incrementer-1) = '\n';
incrementer++;
}
The first loop goes up to the size and inserts the characters into the char* in their positions. When the number is done, it increments the incrementer and adds the newline character.
The second loop goes down in number, doing the same things but this time decrementing the number variable. These two variables start at 1, as that's the start of the "pyramid".
*(print_string+i+incrementer-1) = 48+number;
There is a restriction here, in that if you exceed the number 9 your output will print whatever the ASCII representation of 58 is, so if you want to go above 9, you need to change that.
The for loop just prints the final string "repeat" times as wanted. The newline in the printf() function is not necessary, as the final string contains a newline character at the end, I left it in though. The downside of this implementation is that you're using a char* rather than some other sophisticated method.
Dont forget to free the char* when you're done, and don't forget to add user input error-checking.
#include <stdio.h>
#include <stdlib.h>
void clear(FILE *stream)
{
int ch; // read characters from stream till EOF or a newline is reached:
while ((ch = fgetc(stream)) != EOF && ch != '\n');
}
int main(void)
{
int min, max, count;
while (scanf("%d %d %d", &min, &max, &count) != 3 || // repeat till all 3 fields read successfully and
!min || !max || !count || min > max) { // only accept positive numbers as input
fputs("Input error!\n\n", stderr); // and make sure that the max is greater than the min
clear(stdin); // remove everything from stdin before attempting another read for values
}
puts("Hello world\n");
for (int i = 0; i < count; ++i) { // output the triangle count times
for (int row = min; row <= max; ++row) { // count row from min to max
for (int n = min; n <= row; ++n) // print row (row-min) times
printf("%d ", row);
putchar('\n'); // add a newline after every row
}
for (int row = max - 1; row >= min; --row) { // count from max-1 to min
for (int n = min; n <= row; ++n) // same as above: print row (row-min) times
printf("%d ", row);
putchar('\n'); // add a newline after every row
}
putchar('\n'); // add a newline between repetitions
}
puts("Bye world\n");
}
I'm currently learning the C programming language, and I'm having some issues with it.
I'm getting Segmentation Error quite a lot when dealing with string (A.K.A char tables)
Here a simple algorithm just to delete the 'e' letter in the input string.
Example:
"hackers does exist" ->>> "hacks dos xist"
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{
char T[200];
int j,i,l,times=0;
printf("Entre THE TXT\n");
gets(T);
while (T[i] != '\0')
{
l++;
i++;
}
for (i=0;i<l;i++)
{
if ( T[i] == 'e')
{
times++;
}
}
l=l-times;
i=0;
j=0;
while (i<l)
{
if ( T[j] != 'e')
{
T[i]=T[j];
i++;
j++;
}
else j++;
}
for (i=0;i<l;i++)
{
printf("%c",T[i]);
}
return 0;
}
Can you please tell me what I did wrong?
PS: I have noticed that each time I do incrementation as j++ in this code I will get the Segmentation Error... I really don't understand why.
Initialize i, j, l variables. Since uninitialized local variables are indeterminate. Reading them prior to assigning a value results in undefined behavior.
You are accessing the i and l variable without initialization.
while (T[i] != '\0')
{
l++;
i++;
}
Initialize as below.
int j = 0, i = 0, l = 0, times = 0;
As kiran Biradar already answered you only missed to initialize your integers.
You have several options here. I'll write them from most common to most discouraged.
Most used form, verbose but easier to maintain later.
int i = 0;
int j = 0;
int l = 0;
int times = 0;
Short form 1:
int i = 0, j = 0, l = 0, times 0;
Short form 2:
int i, j, l, times;
i = j = l = times = 0;
I'd suggest you also to use the features of at least the C99 Standard and reduce the scope of your variables completely. (Yes I know it's possible with {}-Blocks but I kinda like for-loops, if you iterate completely over something.
Hence my suggestion for your code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h> // str(n)len
int main(void) // argv/argc is never used
{
char text[200];
printf("Entre THE TXT\n");
if (fgets(text, sizeof(text), stdin) == NULL) // fgets as gets is deprecated
exit(EXIT_FAILURE);
size_t len = strlen(text); // returns number of Characters excluding '\0'
if (len > 0 && text[len-1] == '\n') { // strip newline if present from fgets
text[len-1] = '\0';
}
unsigned int times = 0;
for (size_t i=0; i<len; i++) {
if (text[i] == 'e') {
times++;
}
}
// I'd prefer to use a `newlen` variable
len -= (size_t) times;
for (size_t j=0, i=0; i < len; j++) {
if (text[j] != 'e') {
text[i] = text[j];
i++;
}
}
text[len] = '\0'; // just for safety reasons terminate string properly
puts(text); // Use puts instead of calling printf several times.
return 0;
}
Further improvements:
Actually the times could be eliminated, as it's not really used to delete es.
So just remove the times block and all lines with it.
I am self teaching C programming.
I am trying to count number of int present in given string which are separated by space.
exp:
input str = "1 2 11 84384 0 212"
output should be: 1, 2, 11, 84384, 0, 212
total int = 6
When I try. It gives me all the digits as output which make sense since I am not using a right approach here.
I know in python I can use str.split (" ") function which can do my job very quickly.
But I want to try something similar in C. Trying to create my own split method.
#include <stdio.h>
#include <string.h>
void count_get_ints(const char *data) {
int buf[10000];
int cnt = 0, j=0;
for (int i=0; i<strlen(data); i++) {
if (isspace(data[i] == false)
buf[j] = data[i]-'0';
j++;
}
printf("%d", j);
}
// when I check the buffer it includes all the digits of the numbers.
// i.e for my example.
// buf = {1,2,1,1,8,4,3,8,4,0,2,1,2}
// I want buf to be following
// buf = {1,2,11,84384,0,212}
I know this is not a right approach to solve this problem. One way to keep track of prev and dynamically create a memory using number of non space digits encountered.
But I am not sure if that approach helps.
You want to build your number incrementally until you hit a space, then put that into the array. You can do this by multiplying by 10 then adding the next digit each time.
void count_get_ints(const char *data) {
int buf[10000];
int j = 0;
int current_number = 0;
// Move this outside the loop to eliminate recalculating the length each time
int total_length = strlen(data);
for (int i=0; i <= total_length; i++) {
// Go up to 1 character past the length so you
// capture the last number as well
if (i == total_length || isspace(data[i])) {
// Save the number, and reset it
buf[j++] = current_number;
current_number = 0;
}
else {
current_number *= 10;
current_number += data[i] - '0';
}
}
}
I think strtok will provide a cleaner solution, unless you really want to iterate over every char in the string. It has been a while since I did C, so please excuse any errors in the code below, hopefully it will give you the right idea.
#include <stdio.h>
#include <stdlib.h>
int main() {
char str[19] = "1 2 11 84384 0 212";
const char s[2] = " ";
char *token;
int total;
total = 0;
token = strtok(str, s);
while (token != NULL) {
printf("%s\n", token);
total += atoi(token);
token = strtok(NULL, s);
}
printf("%d\n", total);
return 0;
}
You can check the ascii value of each character by doing c-'0'. If it's between [0,9], then it's an integer. By having a state variable, when you're inside an integer by checking if a given character is a number of space, you can keep track of the count by ignoring white space. Plus you don't need a buffer, what happens if data is larger than 10,000, and you write pass the end of the buffer?, undefined behavior will happen. This solution doesn't require a buffer.
Edit, the solution now prints the integers that are in the string
void count_get_ints(const char *data) {
int count = 0;
int state = 0;
int start = 0;
int end = 0;
for(int i = 0; i<strlen(data); i++){
int ascii = data[i]-'0';
if(ascii >= 0 && ascii <= 9){
if(state == 0){
start = i;
}
state = 1;
}else{
//Detected a whitespace
if(state == 1){
count++;
state = 0;
end = i;
//Print the integer from the start to end spot in data
for(int j = start; j<end; j++){
printf("%c",data[j]);
}
printf(" ");
}
}
}
//Check end
if(state == 1){
count++;
for(int j = start; j<strlen(data); j++){
printf("%c",data[j]);
}
printf(" ");
}
printf("Number of integers %d\n",count);
}
I believe the standard way of doing this would be using sscanf using the %n format specifier to keep track of how much of the string is read.
You can start with a large array to read into -
int array[100];
Then you can keep reading integers from the string till you can't read anymore or you are done reading 100.
int total = 0;
int cont = 0;
int ret = 1;
while(ret == 1 && total < 100) {
ret = sscanf(input, "%d%n", &array[total++], &cont);
input += cont;
}
total--;
printf("Total read = %d\n", total);
and array contains all the numbers read.
Here is the DEMO
Example using strtol
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
#include <ctype.h>
int count_get_ints(int output[], int output_size, const char *input) {
const char *p = input;
int cnt;
for(cnt = 0; cnt < output_size && *p; ++cnt){
char *endp;
long n;
errno = 0;
n = strtol(p, &endp, 10);
if(errno == 0 && (isspace((unsigned char)*endp) || !*endp) && INT_MIN <= n && n <= INT_MAX){
output[cnt] = n;
while(isspace((unsigned char)*endp))
++endp;//skip spaces
p = endp;//next parse point
} else {
fprintf(stderr, "invalid input '%s' in %s\n", p, __func__);
break;
}
}
return cnt;
}
int main(void) {
const char *input = "1 2 11 84384 0 212";
int data[10000];
int n = sizeof(data)/sizeof(*data);//number of elements of data
n = count_get_ints(data, n, input);
for(int i = 0; i < n; ++i){
if(i)
printf(", ");
printf("%d", data[i]);
}
puts("");
}
Assuming you don't have any non-numbers in your string, you can just count the number of spaces + 1 to find the number of integers in the string like so in this pseudo code:
for(i = 0; i < length of string; i++) {
if (string x[i] == " ") {
Add y to the list of strings
string y = "";
counter++;
}
string y += string x[i]
}
numberOfIntegers = counter + 1;
Also, this reads the data between the white spaces. Keep in mind this is pseudo code, so the syntax is different.
So basically what my program did before i had to change it so that it would accept arbitrary values, was to take x-amount of words and the size of the words would also be arbitrary. (both are user inputted). I did this via a multiArray.
Then sorted according to alphabetical-order.
I'm just going to put it out there as my code is shit and I'm very unfamiliar with the usage of arbitrary-strings and pointers. I've read up on it in the manual but the concept needs to sink in a little bit first i believe. Anyhow, I get the error: "Abort trap: 6" when i run the program. Could anyone please help me fix this problem so that i can see how the code would look like if it was actually working, i think that would help me understand both pointers and allocating memory a lot better. Forever in debt if you do.
Current code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_LENGTH 10
int main(){ //8
char *name;
char tname[] = {0};
char temp[] = {0};
int i=0, j=0, n=0;
ssize_t bytes_read;
size_t bytes_number;
printf("Enter the amount of words you want to input: ");
scanf("%d", &n);
printf("Enter %d words: ",n);
bytes_number = MAX_LENGTH;
name = (char *) malloc (bytes_number+ 1);
bytes_number = 0;
bytes_read = getline(&name, &bytes_number, stdin);
if (bytes_read == -1){
puts("ERROR!");
free(name);
}
for (i = 0; i < n; i++){
strcpy(&tname[i], &name[i]);
}
for (i = 0; i < n - 1 ; i++){
for ( j = i + 1; j < n; j++){
if (strcmp(&name[i], &name[j]) > 0){
strcpy(temp, &name[i]);
strcpy(&name[i], &name[j]);
strcpy(&name[j], temp);
}
}
}
printf("\n------------------------------------------\n");
printf("%-3s %4s %11s\n", "Input","|", "Output");
printf("------------------------------------------\n");
for (i = 0; i < n; i++)
{
printf("%s\t\t%s\n", &tname[i], &name[i]);
}
printf("------------------------------------------\n");
}
This
strcpy(&tname[i], &name[i]);
is completely wrong, if you just want to copy all the characters, then it's just
strcpy(tname, name);
which is equivalent to
for (size_t i = 0 ; name[i] != '\0' ; ++i)
tname[i] = name[i];
using strcpy(&tname[i], &name[i]) is wrong because it will copy all the bytes from name until '\0' is found, at every loop starting at the i-th character.
But this will fail again because tname is does not have room, it's an array with just one element.
Since you want to sort the strings, you DO NOT NEED TO COPY them. Just swap the pointers. Also
char temp[] = {0};
only allocates 1 character, thus
strcpy(temp, name);
will invoke Undefined Behavior.
Try this, maybe it's what you need
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int
main(void)
{
char **words;
char *temp;
int word_count;
int actual_count;
char *word;
size_t length;
int result;
printf("Enter the amount of words you want to input: ");
if (scanf("%d%*c", &word_count) != 1)
return -1; // Input error
printf("Enter '%d' words:\n", word_count);
words = NULL;
word = NULL;
result = -1;
actual_count = 0;
length = 0;
for (int i = 0 ; i < word_count ; ++i)
{
char **pointer;
printf("Word(%d) > ", i + 1);
if ((length = getline(&word, &length, stdin)) <= 0)
goto cleanup;
// Grow the array of words
pointer = realloc(words, (i + 1) * sizeof(*pointer));
if (pointer == NULL)
goto cleanup; // Memory Exhausted
// Now it's safe to overwrite `words'
words = pointer;
words[i] = malloc(length);
if (words[i] == NULL)
goto cleanup; // Memory Exhausted
memcpy(words[i], word, length);
words[i][length - 1] = '\0'; // Replace '\n' with '\0'
actual_count += 1;
}
printf("Input : ");
for (int i = 0 ; i < actual_count ; ++i)
printf("%s\t", words[i]);
printf("\n");
for (int i = 0; i < actual_count - 1 ; i++)
{
for (int j = i + 1 ; j < actual_count ; ++j)
{
if (strcmp(words[i], words[j]) <= 0)
continue;
temp = words[i];
words[i] = words[j];
words[j] = temp;
}
}
printf("Output: ");
for (int i = 0 ; i < actual_count ; ++i)
printf("%s\t", words[i]);
printf("\n");
result = 0;
cleanup:
free(word);
for (int i = 0; i < actual_count ; i++)
free(words[i]);
free(words);
return result;
}
Note: This would consider an empty word (made completely of white space characters), as a valid word.