0

A piece of a program i am writing replaces a certain value in an array with the next value in the array. However, it ends up with the last two values in the array being identical. Is there a way to just replace the last value with NULL?

this is the current output

found it again
Array value 0: cat:
Array value 1: file1.txt:
Array value 2: output.txt:
Array value 3: output.txt:
Array value 4: (null):
Array value 5: (null):
This is the first line in file1.txt
This is the last line

this is the output when i try to replace the last value will null, but it returns a segmentation fault

found it again
Array value 0: cat:
Array value 1: file1.txt:
Array value 2: output.txt:
Array value 3: (null):
Array value 4: (null):
Array value 5: (null):

here is the full code

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>

#define BUFFERSIZE 1024

int main(int argc, char* argv[])
{
    int fd_out = dup(STDOUT_FILENO);
    int fd_in = dup(STDIN_FILENO);
    
    argc++;

    char buf[BUFFERSIZE];
    int n;
        printf("Please enter commands: \n");

    while ((n = read(STDIN_FILENO, buf, BUFFERSIZE)) > 0)
        {
        buf[n] = 0;
        buf[strlen(buf)-1] = '\0';
        int i = 0;
        char* array[10];
        char* token1 = strtok(buf, " ");

        while ((token1 != NULL))
        {
            array[i++] = token1;
            token1 = strtok(NULL, " ");
            
        }//while

        array[i] = NULL;

        if (strcmp(buf, "exit") == 0)
        {
            break;
        }//if
        
        for (int j = 0; j < i; j++) 
        {
            if (!strcmp(array[j], ">"))
            {
                char* filename_out = array[j+1];
                printf("STDOUT redirected\n");
                printf("found it\n");
                int file_out = open(filename_out, O_WRONLY | O_CREAT, 0777);
                int file2_out = dup2(file_out, 1);
                
                for(int k = j; k < i-1; k++)
                {
                    array[k] = array[k + 1];
                }//if
                
                array[i] = NULL;
                printf("found it again\n");

                if ((file_out | file2_out) == -1)
                {
                    return 1;
                }//if

                //array[i-1] = NULL;

                            for (int j = 0; j < i+2; j++)
                            {
                                    printf("Array value %d: %s:\n", j, array[j]);
                            }//for*/
            }//if
            if (!strcmp(array[j], "<"))
            {
                char* filename_in = array[j+1];
                printf("STDIN_FILENO redirected\n");
                int file_in = open(filename_in, O_WRONLY | O_CREAT, 0777);
                int file2_in = dup2(file_in, 0);

                                for(int l = j; l < i - 1; l++)
                                {
                                        array[l] = array[l + 1];
                                }//for
                
                if ((file_in | file2_in) == -1)
                {
                    return 1;
                }//if
            }
        }//for

            for (int i = 1; i < argc; i++)
            {
            pid_t pid;
            
            if (argc >= 1) 
            {
                if ((pid = fork()) < 0) 
                {
                    perror("fork");
                }//if
                else if (pid == 0) 
                { // child process
                    if (execvp(array[0], array) == -1) 
                    {
                        perror("execvp");
                        return EXIT_FAILURE;
                    } // if
                }//else if
                else 
                {   // parent process
                    int status;
                    wait(&status);
                    //int again_out = dup2(fd_out, 1);
                    //int again_in = dup2(fd_in, 0);
                    if ((again_out | again_in) == -1)
                    {
                        return 1;
                    }
                    printf("Please enter commands again: \n");
                    
                }//else     
            }//if
            else 
            {
                fprintf(stderr, "Please specify the name of the program to exec as a command line argument\n");
                return EXIT_FAILURE;
            }//if
        }//for
    }//while
    if (n == -1) perror("read");
}//main

i tried to use array[i-1] = NULL; (where i is the size of the array) but it returns a segmentation fault

sgrandom
  • 27
  • 3
  • OT: You null-terminate `buf` *twice*. – Some programmer dude Nov 25 '22 at 17:35
  • As for your problem, please use a [*debugger*](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) to step through your code line by line while monitoring variables and their values. – Some programmer dude Nov 25 '22 at 17:37
  • 1
    And a general tip: Don't write large parts of code without testing. Only write a little bit of code, build with extra warnings enabled (treated as errors) and test that piece of code thoroughly. Then add the next list piece of code, and so on. When there is a problem, it's usually because of the last little piece of code you added, which makes it much easier to debug (and create a [mre] to help with the debugging). – Some programmer dude Nov 25 '22 at 17:40
  • @Someprogrammerdude The code itself works exactly how I've written it. I am running into an error when I try to change the last value in the array. I know where the problem is and I'm asking what is the best way to change the last value in an array. – sgrandom Nov 25 '22 at 17:54
  • 1
    Please — create functions to separate unrelated chunks of code. Even if only used once, they make it easier to understand the program. It isn't clear why you're using `fork()` and `execvp()` in a program that's having problems manipulating an array of strings. Please learn how to create an MCVE ([Minimal, Complete, Verifiable Example](https://stackoverflow.com/help/mcve) — or MRE or whatever name SO now uses) or an SSCCE ([Short, Self-Contained, Correct Example](http://sscce.org/)) — the same idea by a different name. If you've got 4 or more levels of indentation, it may be time to refactor. – Jonathan Leffler Nov 25 '22 at 17:55
  • Yes the code works as you have written it. But unfortunately that doesn't mean you have written it correctly. If you did, then you wouldn't have a problem, would you? So you must debug. And if you can't do that and want our help then you need to create a proper [mre], with emphasis on the ***minimal*** part, but of course also the reproducible part. – Some programmer dude Nov 25 '22 at 20:18
  • And please take some time to read [the help pages](http://stackoverflow.com/help), take the SO [tour], read [ask], as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). – Some programmer dude Nov 25 '22 at 20:18

0 Answers0