This line arr = (char*)malloc (2 * sizeof (char)); will allocate memory for 2 bytes only. But you are overwriting the memory by accessing the more 8 or more than 8 byes. If you access more than two byes means, it will give some unpredictable issue. In case you want more memory please follow the below code.

#define USER_SIZE 10
arr = (char*)malloc ( USER_SIZE * sizeof (char));

Assign the value in USER_SIZE macro and then allocate the memory as much as you want.

Example for 2D pointer ( 5 X 10 )

#define ROW 5
#define COLUMN 10
main()
{
  unsigned char **p = NULL, colum = 0;
  p = malloc ( ROW * sizeof ( unsigned char *) );
  for (;colum< ROW; ++colum )
  {
    p[colum] = malloc (COLUMN * sizeof (unsigned char  ));
  }
}
Answer from mahendiran.b on Stack Overflow
Top answer
1 of 2
5

This line arr = (char*)malloc (2 * sizeof (char)); will allocate memory for 2 bytes only. But you are overwriting the memory by accessing the more 8 or more than 8 byes. If you access more than two byes means, it will give some unpredictable issue. In case you want more memory please follow the below code.

#define USER_SIZE 10
arr = (char*)malloc ( USER_SIZE * sizeof (char));

Assign the value in USER_SIZE macro and then allocate the memory as much as you want.

Example for 2D pointer ( 5 X 10 )

#define ROW 5
#define COLUMN 10
main()
{
  unsigned char **p = NULL, colum = 0;
  p = malloc ( ROW * sizeof ( unsigned char *) );
  for (;colum< ROW; ++colum )
  {
    p[colum] = malloc (COLUMN * sizeof (unsigned char  ));
  }
}
2 of 2
2

What you are doing is called buffer overflow by writing beyond the bounds of memory allocated by malloc call. The compiler doesn't do bounds checking (it assumes you know what you are doing, and you only pay for what you use) and allow you to compile and run. However, it will lead to undefined behaviour and your program may crash. You shouldn't rely on such behaviour.

You, the programmer, has to make sure that you don't do illegal memory access. You should not cast the result of malloc. Also, malloc can fail to allocate memory in which case it returns NULL, the null pointer, which you should take care of. You can combine the two statements into one.

int length = 8; // you can also use a macro
char *arr = malloc(length * sizeof *arr);
if(arr) {
    // malloc call successful
    // do stuff with arr
} 
🌐
Delft Stack
delftstack.com › home › howto › print char array in c
How to Print Char Array in C | Delft Stack
February 2, 2024 - In the first printf statement, we use %.3s to print only the first three characters of the array arr. In the second printf, we use %.*s to specify the length as 4, printing the first four characters. This flexibility can be useful when you need to extract substrings or print a portion of the character array.
Discussions

How to print a char array in C through printf? - Stack Overflow
Also you can initialize your char arrays with string literals too: char mystring[6] = "alien"; //the zero is put by the compiler at the end · Also: Functions that operate on C Style Strings (e.g. printf, sscanf, strcmp,, strcpy, etc) need zero to know where the string ends More on stackoverflow.com
🌐 stackoverflow.com
C Dynamic char array - Stack Overflow
Expanding array dynamicly after user enter string in function dynamic_array My Problem seems to be when i try to use the extended array agian in main after i dynamic_array returns true. After func... More on stackoverflow.com
🌐 stackoverflow.com
May 23, 2017
How to declare a dynamic array of char in c - Stack Overflow
Connect and share knowledge within a single location that is structured and easy to search. Learn more about Teams ... I'm trying to declare an array of char dynamically, what I need to do is adding the newest character to the string which works fine, the problem is that when I try to print it out, ... More on stackoverflow.com
🌐 stackoverflow.com
[question] How to print multiple chars from array?
char letters[] = { 'a','b','c','d' }; printf ("%.*s", 3, letters); Output is: abc More on reddit.com
🌐 r/cprogramming
9
3
August 12, 2021
🌐
Quora
quora.com › How-can-I-print-out-the-arrays-of-character-as-a-single-word-or-a-string-in-the-C-language
How to print out the arrays of character as a single word or a string in the C language - Quora
Answer (1 of 3): [code]#include int main() { char arr1[] = { 'W', 'e', 'l', 'c', 'o', 'm', 'e', '\0' }; char arr2[] = "Good bye!"; /* Print character array using printf */ printf( "arr1 is %s\n", arr1 ); printf( "arr2 is %s\n", arr2 ); /* Print character array...
Top answer
1 of 3
3

To get some memory to your string, you have to tell malloc how many bytes of memory you want. sizeof(char) returns 1, therefore, you'll only have 1 byte. In C, strings are terminated by the NULL byte (\0), and printf and others will print until they find that NULL terminator.

If you do something like this:

char *str = malloc(1);
*str = 'a';
printf("%s", str);

You will probably get a very strange output, since you have no NULL terminator.

When you use the unsigned x; str = malloc(x);, it's actually undefined how many bytes you have, since that x variable is not initialized.

Since your question is very unclear, what I can tell you (from what I think you're asking) is how to actually get space for a string of 63 characters plus the NULL terminating byte.

char *str = malloc(64);
strcpy(str, "Stack Overflow");
printf("%s", str);

That will do it.

Also note that the memory block returned by malloc will not be zeroed, therefore you can't possibly know what's in it (that could be the reason you're getting garbage when you're printing).

I recommend you read about memory allocation in a good C book or in Wikipedia...


After your edit and "MCVE"

I made some edits to what I think it is you want. The modifications are explained in the comments of the source. Let me know if you have any doubts.

#include <stdio.h>  /* printf */
#include <stdlib.h> /* malloc, free, realloc */
#include <string.h> /* strcat */
#include <ctype.h>  /* isalnum */
#include <conio.h>  /* getch */

int main(void)
{
    char add[2];
    char str2[200];
    char c;
    int temp = -1;
    int num = 0;
    char *str3;

    /* I just think 'count' is an int, since you didn't put it in the code, 
     * I also deduced that @count will be used as the length of @str3 
     */
    int count;

    /* Here, count is not initialized, so you MUST initialize it in order 
     * to call malloc with it! Since it seems you want to add character by
     * character using realloc, then we just malloc() 2 bytes - 1 for a 
     * character and one for the NULL terminator.
     */
    count = 2;
    str3 = malloc(count);

    /* You will be using @strcat to append strings to @str3, so you need
     * to put a NULL terminator in it, because strcat will look for that
     * NULL byte to find where it should append
     */
    *str3 = 0x0;

    while((c = getch()) != '\r') {
        for (int i = 0;i < 200; i++) {
            if (str2[i] =='\0') {
                num = i;
                break;
            }
        }

        if ((temp == -32) || (temp == 0)) {
            /* empty */ 
        } else {
            if(isalnum((char)c) == 0)
            {
                if((c == '\'') || (c == -118) || (c == -115) || (c == -107) || (c == -123) || (c == -105)|| (c == 32))
                {
                    /* this is not the optimal way of using realloc, because
                     * you should first check for errors, but will do for
                     * this example.
                     * You must assign the returned value of realloc to str3. 
                     *
                     * Also, since @count contains the length
                     * of @str3, you need to increment it.
                     */
                    str3 = realloc(str3, ++count);
                    printf("true: %c\n",c);
                    add[1] = '\0';
                    add[0] = c;
                    strcat(str3,add);
                    strcat(str2,add);
                    printf("str2: %s\n",str2);
                    printf("str3: %s\n",str3);
                } else if (c == 8) {
                    printf("Deleting something...\n");
                }
            } else {
                /* see notes above on realloc */
                str3 = realloc(str3, ++count);
                printf("true: %c\n",c);
                add[1] = '\0';
                add[0] = c;
                strcat(str3,add);
                strcat(str2,add);
                printf("str2: %s\n",str2);
                printf("str3: %s\n",str3);
            }
        }
        printf("ASCII Code: %d\n",c);
        temp = c;
    }
    return 0;
}
2 of 3
0

In the first two cases, you are only allocating enough space for a single char. If you attempt to write more than one to that block of memory, you'll write past the end of the memory that was allocated for you. Doing so invokes undefined behavior, which in this case manifests as printing strange characters.

In the third case, you allocate x bytes of memory, however x is uninitialized and has an indeterminate value. Reading an indeterminate value is also undefined behavior. In this case it happens to work because the indeterminate value happens to be a valid value and is large enough to hold the string you want, however you can't depend on that behavior.

You need to allocate a byte for every character that you'll need, plus 1 for the terminating null byte that ends a string in C.

🌐
Reddit
reddit.com › r/cprogramming › [question] how to print multiple chars from array?
r/cprogramming on Reddit: [question] How to print multiple chars from array?
August 12, 2021 -

i want to be able to print out multiple values from an array without having to re-write the char name and array number multiple times, is this possible? example...

char letters[] = {'a','b','c','d'};
printf("%c%c%c%c", letters[0], letters[1], letters[2]);

i want to make that code cleaner and easier to use/understand. I thought i'd be able to use

printf("%c", letters[0][1][2]);

or seperated by commas, but that doesn't work either. Any suggestions?

Find elsewhere
🌐
Quora
quora.com › How-do-I-dynamically-allocate-a-char-array-using-a-malloc-function-in-C
How to dynamically allocate a char array using a malloc function in C - Quora
In order to allocate memory dynamically using C language the following code will be enough: char *s = (char *)malloc(20 * sizeof(char)); The above line allocates memory for storing 20 characters or in fact 19 ch...
🌐
Linux Hint
linuxhint.com › print-char-array-through-printf-c-programming
How to Print a Char Array in C Through printf – Linux Hint
To print the first array using for loop and printf command. The %c in printf command is used to define that the character is required to print, if you add %d instead of %c, it will display the internal numeric representation of the characters inside the array:
🌐
Cplusplus
cplusplus.com › forum › beginner › 284775
Char array to dynamic char array - C++ Forum
.. cin.getline (stringToUpper, '/n'); ... stringToUpper = new char[arraySize]; basically, reverse the above with the appropriate doctoring of the in between statements etc. Note that it is also really important that arraysize HAS A VALUE before you get that many bytes.
🌐
Stack Overflow
stackoverflow.com › questions › 55875518 › creating-a-dynamic-char-array
c - Creating a dynamic char array - Stack Overflow
Note you do not have to read two times the file, you can use malloc then realloc to increase the size of the (really) dynamic array · A Proposal : #include <stdlib.h> #include <stdio.h> #include <string.h> int main() { char ** array = malloc(0); size_t size = 0; FILE * file; char * line; size_t len; ssize_t read; file = fopen("wordsEn.txt", "r"); if(file == NULL) { printf("Error coudl not open wordsEn.txt\n"); return -1; } while (line = NULL, len = 0, (read = getline(&line, &len, file)) != -1){ array = realloc(array, (size+1) * sizeof(char *)); array[size++] = line; } free(line); /* do not fo
🌐
AirtelWireless
airtelwireless.ca › update › c-print-char-array
c print char array
September 25, 2024 - This creates a character array that holds the string "Hello, World!" along with a null character at the end. The most straightforward way to print a char array is by using the printf() function from the standard input-output library.
🌐
Reddit
reddit.com › r/cpp_questions › how do i cin and cout dynamic char arrays in c++? (example names)
r/cpp_questions on Reddit: How do I cin and cout dynamic char arrays in c++? (example names)
August 8, 2021 -

hey! I am stuck on this question, I have to cin and cout a dynamic array of characters (not using library function/ c++ string types), here are the two issues i am facing:

  1. I do not know how long the name would be so should I just take a precondition that it should be smaller than let's say 100? or is there a way that I can create a dynamic array without specifying coloum size?

  2. this code that i came up with is producing weird result and i have no clue how to correct it T_T

I would be really thankful if you all can help me with this T_T.

my needed output should look something like:

enter name #1: abc def

enter name #2: ghi jkl...

.

.

.

enter name #n: nnn mmm

int main() 
{
	int n, j=0;
	cout<<"How many names do you want to enter ? ";
	cin>>n;
	char** name = new char*[n];
	for(int i=0; i<n; i++)
	{
		name[i]=new char[100];
	}
	for(int i=0; i<n; i++)
	{
		cout<<"enter name #"<<i+1 <<" :";
		do
		{
			cin>>name[i][j];
			j++;
			
		}while(name[i][j]!='\n');
	}
	for(int i=0; i<n; i++)
	{
	    for(int j=0; name[i][j]!='\n' ; j++)
	    {
	        cout<<name[i][j];
	    }
	    cout<<endl;
	}
}

Edit: Thank You so much for helping me with this problem however I figured a way to do it, it's definitely not the best or the most useful but our professor won't vibe with any other straight ways lmao here's what I came up with and the output I get, please let me know what yall think!

int main() 
{
	int n;
	
	cout<<"How many names do you want to enter ? ";
	cin>>n;
	char** lastname = new char*[n];
	for(int i=0; i<n; i++)
		lastname[i]=new char[100];
		
	char ** firstname = new char*[n];
	for(int i=0; i<n; i++)
	    firstname[i]=new char[100];
		
	for(int i=0; i<n; i++)
	{
		cout<<"enter name #"<<i+1 <<" :";
	   	   cin>>firstname[i]>>lastname[i];
	   	   
	}
	
	for(int i=0; i<n; i++)
	{
	    cout<<firstname[i]<<" "<<lastname[i];
	    cout<<endl;
	}
	
}

/* OUTPUT :
How many names do you want to enter ? 3
enter name #1 :Fucker Certified
enter name #2 :Flex Offender
enter name #3 :Billy Balls
Fucker Certified
Flex Offender
Billy Balls
*/

I am pretty sure it's not the most efficient but this was all I could think of T_T

once again Thank You so muchhh!!

Top answer
1 of 2
10
That is the C way and therefore is an absolutely awful C++ question. Anyway you need to use this function: https://en.cppreference.com/w/cpp/io/basic_istream/getline Every time the function fails because the buffer is too small you will have to release the buffer and reserve a larger buffer.
2 of 2
4
Yikes! You can't use either getline or standard string? Your teacher is shit. I don't care what they think they're doing, teaching you low level semantics - this isn't the way to do it. By the time you're here, writing user IO, such lessons should be behind you. Arbitrary limits are the mark of a bad teacher and a bad lesson plan. With that aside, you need to implement your own string and your own getline, and apparently your own vector. I hope you already know how to write functions, and can use those. If you're not allowed to use a function, consider dropping out or petitioning to switch to a teacher who has a fucking clue how to do their job. To implement a dynamic container, you need 3 pointers: using pointer = T*; using reference = T&; pointer first, last, total; Then to allocate: void alloc(size_t size) { first = new T[size]; last = first; total = first + size; } Reallocation is always a doubling: size_t cap() { return total - first; } size_t size() { return last - first; } void copy_to(pointer dest) { for(auto iter = first; iter != last; ++iter) { dest[iter - first] = *iter; } } void realloc() { auto tmp_cap = cap(); auto tmp_size = size(); pointer tmp = new T[tmp_cap * 2]; copy_to(tmp); delete first; first = tmp; last = first + tmp_size; total = first + tmp_cap; } Wrap this stuff up in a class. This is basically how vectors and strings work. If you can make it a template, then you can use your new container type for both. You'll have to flesh out the rest of the code, including adding a new element to the buffer, probably with a push_back method. You'll have to see if you have capacity to add one more, and if not, reallocate. Otherwise, you add your new element to last, then ++last. Then you need to replicate getline. This is simply extracting one character at a time and checking if it's equal to a delimiter. If it isn't the delimiter, you push back onto your string. If it is the delimiter, you disregard it and stop your extracting loop. I'll leave this one entirely up to you. Finally, you need to be able to print your string type: ostream &operator <<(ostream &os, const your_string_type &str) { for(size_t i = 0; i < str.size(); ++i) { os << str[i]; } return os; } This is "operator overloading" syntax. You can write custom operators for almost anything. I made the presumption you would have written a reference operator[](size_t offset) hint hint for your string type. I'm omitting a lot because I'm not going to do your homework for you, but I hope I've given you some insight. If you can't use any of this for your homework, then I hope I've kind of blown your mind.
🌐
CopyProgramming
copyprogramming.com › howto › c-dynamic-char-array
C Dynamic char array
June 25, 2023 - for (int j = 0; j < leng; j++) // print array { cout< To display the array size, you can simply utilize the previously defined variable, leng . cout << "size of array after saving " << leng << " chars: " << leng + 1 << endl; C++ Dynamic array of char arrays, You are just copying pointers, not strings.
Top answer
1 of 2
2

This is problematic:

char Array[SIZE], *Array_ptr = strtok(Array, " .");

You are declaring the array, then trying to use strtok on the uninitialized array. You probably meant to do this:

char Array[SIZE], *Array_ptr = 0;
StrInput(Array, SIZE);
Array_ptr = strtok(Array, " .");
2 of 2
1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 10
#define MIN_SIZE 2


void StrInput(char str[], int maxChars);

int main(int argc, char *argv[]){
    char Array[SIZE], *Array_ptr, *strwk;
    StrInput(Array, SIZE);
    int i=0;

    strwk=strdup(Array);//strtok would change the string. so make a copy.
    Array_ptr=strtok(strwk, " .");
    while (Array_ptr != NULL){
        ++i;//countup element
        Array_ptr = strtok(NULL, " .");
    }

    int *Malloc_Array_ptr = (int*)malloc(i* sizeof(int));

    i=0;
    strcpy(strwk, Array);
    Array_ptr = strtok(strwk, " .");
    while (Array_ptr != NULL){
        Malloc_Array_ptr[i] = atoi(Array_ptr);
        ++i;
        Array_ptr = strtok(NULL, " .");
    }
    free(strwk);
    int j;
    //check print
    for(j=0;j<i;++j)
        printf("%d ", Malloc_Array_ptr[j]);
    printf("\n");
//  printf("Show me the money: %s \n", Malloc_Array_ptr);//Malloc_Array_ptr isn't (char*).
    system("PAUSE");  
    return 0;
}

/*----------------------------------------------------------------------*/
void StrInput(char str[], int maxChars){
    int i=0, ch;//str_lenght: unused
    int InputOver = 0;

    printf("input numbers :");
    for(i=0;(ch = getchar()) != '\n';++i){
        if(i > maxChars -1){//-1: for EOS(\0)
            i = maxChars - 1;
            InputOver = !InputOver;//true
            break;
        }
        str[i]=(char)ch;
    }
    str[i]='\0';

    if (InputOver || i<MIN_SIZE){
        printf("Your sumbition dosn't fit the size criteria.\n");
        printf("Please reenter:\n\n");
        while('\n'!= ch){//clear input
            ch = getchar();
        }
        StrInput(str, maxChars);
    }
}
Top answer
1 of 3
18

There are a number of things I would change here, so I'm going to go through the process incrementally, applying changes to the whole file in passes rather than in chunks. I think this should make it more clear why the changes are implemented.


C99 Note

You should have access to, at the very least, a C99 compiler. If that's not true, you can ignore this first point, but if it is, you should change your counter declarations to be inside the first for clause.

for (int i=0;i<n;i++)

Pointers

In initArr, you both return the int array and assign it to the provided out parameter, arr. Why? Out parameters make code confusing and hard to follow! They make sense if you're performing the array allocation somewhere else, but since you're performing the array allocation inside initArr, just drop the arr parameter and return the value.

As a side effect of this, since you no longer need a double pointer, you can replace your dereferences with simple array accesses.

int * initArr (int n)
{
    int * arr = (int *) malloc(sizeof(int*)*n);
    printf("size is %d\n", sizeof(arr));
    for (int i=0;i<n;i++)
    {
        arr[i]=i+10;
    }
    return arr;
}

Next, why are you passing a double pointer (int**) to printArr? More importantly, why does printArr have a return value if it's a purely side-effectful function? Change the parameter to int* and make the function return void.

void printArr (int * arr, int n)
{
    for (int i=0;i<n;i++)
    {
        printf("Arr element %d is %d\n", i, arr[i]);
    }
}

This also simplifies the main function.

int main(void) {
    int * arr2 = initArr(10);
    printArr(arr2,10);

    return 0;
}

Next, let's take a look at the allocation itself (the one in initArr). First of all, you cast to (int *) manually, which is unnecessary and downright discouraged in C. If you're using C++, it's necessary (though you shouldn't need malloc in C++, anyway), but with a C compiler, just drop it.

Second of all, you are not actually allocating the right data! You're allocating n slots for int* values—int pointers. You actually want int data. This might not matter depending on your architecture and compiler, but it's still poor code. Fortunately, you can actually fool-proof this—don't pass an explicit type of sizeof at all! Just deference arr itself, and the compiler will calculate that value's size.

Those changes simplify the allocation to this:

int * arr = malloc(sizeof(*arr)*n);

Finally, the line just after that—the printf line—is useless. It will always print the same value because it's checking the size of a pointer, which is always the same size regardless of type (though it can change on different architectures). That said, the line doesn't make any sense there. A function called initArr shouldn't have side effects, anyway. Just take it out.


Style and Warnings

I'm not sure if you just omitted it from your code, but your code depends on functions declared in external header files in the standard library. Include these at the top of your file.

#include <stdlib.h>
#include <stdio.h>

Next, let's talk about code style. You are writing some very densely-packed expressions in some places. Some whitespace can make code much more readable! For example, change the for loops to this:

for (int i = 0; i < n; i++)

Similarly, change your allocation to this:

int * arr = malloc(sizeof(*arr) * n);

Proper spacing makes code more readable and therefore more maintainable!

Finally, let's talk about pointer declarations. You are declaring your pointers with the asterisks just sort of "floating". This is actually not a bad compromise. Some people prefer them to be grouped with the type (int* foo), others with the name (int *foo). I prefer the former style, so in my final copy of the code, I changed them accordingly, but this is often merely personal preference.


Result

Here is all the code as it stands with the above changes implemented! Not only is it more readable due to style, but it's easier to understand the control flow since it no longer unnecessarily indirects variables via reference.

#include <stdlib.h>
#include <stdio.h>

int* initArr(int n)
{
    int* arr = malloc(sizeof(*arr) * n);
    for (int i = 0; i < n; i++) {
        arr[i] = i + 10;
    }
    return arr;
}

void printArr(int* arr, int n)
{
    for (int i = 0; i < n; i++)
    {
        printf("Arr element %d is %d\n", i, arr[i]);
    }
}


int main(void) {
    int* arr2 = initArr(10);
    printArr(arr2, 10);

    return 0;
}

Extra Notes

Can I use arr[i] anywhere in the functions instead of **arr? (Gave error when I tried it)

You can! But * has lower precedence than array subscript ([]), so you'd need to use grouping operators

(*arr)[i]

This became unnecessary with the other changes, though.

What is the most common way of dealing with arrays when writing professional code? Is my approach correct?

Depends on the situation. Honestly, the best away to handle arrays is to not use them—if you're using a language with any more power than C, you should have higher-level language constructs (std::vector, ArrayList, etc.). However, if you have to use C, abstracting them behind an API is a good start.

One issue I'm encountering is having no way to tell printArr() what the size of the array is.

Yes, in C, arrays are just blocks of memory, so you can't get their length at runtime because it's not stored anywhere! If you wanted to do this, though, you could encapsulate your array in a struct.

typedef struct my_array {
    unsigned int length;
    int* data;
} my_array_t;

You could then return a my_array_t from initArr and pass a my_array_t to printArr, which could use arr.length to get the length.

2 of 3
6
  • Return values

    • initArr communicates the start address via both the return value and a pass-by-reference parameter. It surely is redundant. Normally you'd pick one of two possible signatures:

      int * initArr(int size);
      void initArr(int ** arr, int size);
      

    and stick to it.

    • printArr, as the name suggests, only produces a side effect of values being printed. It has nothing to report back except possibly errors encountered while printing. Make it void printArr(int *, int).
  • (Ab)use of sizeof

    initArr allocates an array of n units of a pointer size. This works by coincidence: in pretty much any platform space taken by a pointer is enough to accomodate an integer. However it is not guaranteed.

    printf("size is %d\n", sizeof(*arr)) is totally misleading. It is equivalent to printf("size is %d\n", sizeof(int *)), and doesn't depend on how many bytes are actually allocated. Try to pass size 0 to initArr.

🌐
IncludeHelp
includehelp.com › code-snippets › declare-and-print-dynamic-array-using-c-pointer.aspx
C - Declare and Print Dynamic Array using C Pointer - IncludeHelp
August 3, 2016 - In this code snippet, we will learn how to declare dynamic memory for one dimensional integer array. In this example, we will declare dynamic array for 5 integer elements, assigning values to them and print values of all elements.
🌐
Studytonight
studytonight.com › c › string-and-character-array.php
String and Character Arrays in C Language | Studytonight
It copies the second string argument to the first string argument. ... #include<stdio.h> #include<string.h> int main() { char s1[50], s2[50]; strcpy(s1, "StudyTonight"); strcpy(s2, s1); printf("%s\n", s2); return(0); }