Problem in cat part in #NI6 in golang

I’m stuck on Stage #NI6

I’ve tried, parsing the arguments on my own, which helped me to pass the echo part, but I can’t pass the cat part.

Here are my logs:

[compile] Moved ./.codecrafters/run.sh → ./your_program.sh
[compile] Compilation successful.
[tester::#NI6] Running tests for Stage #NI6 (Quoting - Single quotes)
[tester::#NI6] [setup] export PATH=/tmp/pineapple/mango/pineapple:$PATH
[tester::#NI6] Running ./your_program.sh
[tester::#NI6] [setup] echo -n "pear raspberry." > "/tmp/cow/f   88"
[tester::#NI6] [setup] echo -n "banana strawberry." > "/tmp/cow/f   11"
[tester::#NI6] [setup] echo "raspberry mango." > "/tmp/cow/f   42"
[your-program] $ echo 'example shell'
[your-program] example shell
[tester::#NI6] ✓ Received expected response
[your-program] $ echo shell     world
[your-program] shell world
[tester::#NI6] ✓ Received expected response
[your-program] $ echo 'hello     script' 'world''example' shell''test
[your-program] hello     script worldexample shelltest
[tester::#NI6] ✓ Received expected response
[your-program] $ cat '/tmp/cow/f   88' '/tmp/cow/f   11' '/tmp/cow/f   42'
[your-program] cat: /tmp/cow/f   88 /tmp/cow/f   11 /tmp/cow/f   42: No such file or directory
[tester::#NI6] ^ Line does not match expected value.
[tester::#NI6] Expected: "pear raspberry.banana strawberry.raspberry mango."
[tester::#NI6] Received: "cat: /tmp/cow/f   88 /tmp/cow/f   11 /tmp/cow/f   42: No such file or directory"
[your-program] 2026/01/03 08:16:48 exit status 1
[tester::#NI6] Assertion failed.
[tester::#NI6] Test failed

And here’s a snippet of my code:

				data, err := Echo(cmdList)
				if err != nil {
					log.Fatal(err)
				}
				execute := exec.Command(cmdList[0], data)

this is how i handle cat and other commands, not echo, echo one is handled separately below, but I can create for cat, echo:

		if cmdList[0] == "echo" {
			if cmd == "echo" {
				continue
			}

			data, err := Echo(cmdList)
			if err != nil {
				log.Fatal("Error", err)
			}
			fmt.Println(data)
			continue

		}

And here is my Echo function

func Echo(cmdList []string) (string, error) {
	content := fmt.Sprint(cmdList[1:])
	realContent := content[1 : len(content)-1]

	opened := false
	// doubleOpened := false
	var result string
	var quotesContent string
	var withoutQuotesContent string
	emitted := false
	inArgument := false

	for _, v := range realContent {
		if v == '\'' {
			//fmt.Println("bar")
			opened = !opened
		}
		//		if v == 39 {
		//			doubleOpened = !doubleOpened
		//		}
		if opened && v != '\'' {
			if withoutQuotesContent != "" {
				if emitted && !inArgument {
					result += " "
				}
				result += strings.Join(strings.Fields(withoutQuotesContent), " ")
				withoutQuotesContent = ""
				emitted = true
				inArgument = true
			}
			quotesContent += string(rune(v))
		} else if !opened {
			if v == '\'' {
				// then it is just closed
				if quotesContent != "" {
					if emitted && !inArgument {
						result += " "
					}
					result += quotesContent
					quotesContent = ""
					emitted = true
					inArgument = true
					//				fmt.Printf("--->%v\n", result)
					//				fmt.Println("baz")
				}
			} else {
				//treat it as normal thing
				if v == ' ' {
					inArgument = false
				}
				withoutQuotesContent += string(rune(v))
				//				fmt.Println("foo")
				// fmt.Println(withoutQuotesContent)
			}
		}
	}
	//	fmt.Println(quotesContent)
	//	fmt.Printf("%q\n", withoutQuotesContent)

	if withoutQuotesContent != "" {
		if emitted && !inArgument {
			result += " "
		}
		result += strings.Join(strings.Fields(withoutQuotesContent), " ")
	}

	return result, nil
}

Any help will appreciated, if above is not clear, please let me know in replies. Thanks.

Hi, thanks for your post!

I’m currently out of the office for the holidays and will be back on January 5. I’ll get back to you as soon as possible once I return.

I don’t know Go, but it looks like exec.Command takes a “splatted list” of args: func Command(name string, arg ...string) *Cmd.

Most crafters probably parses the command into a list of tokens. Then the command or built-ins process them. You; however, make an interesting choice to use Echo to essentially parse. But from what I can tell you only return a single string in result which you then pass as the single splatted argument to Command(cmdList[0], data).

Now the error makes if we consider that cat is reporting cat: <filename>: No such file or directory. Your filename is the single string /tmp/cow/f 88 /tmp/cow/f 11 /tmp/cow/f 42 and not three individual paths.

Edit: since Posix/Linux, unlike say Windows, give programs a list of args, that is what argcand argv is you actually need the ability to split the input into separate pieces. A good starting point for this is your Echo function, but look at the places where you “append” a piece and consider whether that is a separate argument instead.

I have confusion, cat '/tmp/fox/f 81' '/tmp/fox/f 56' '/tmp/fox/f 70' are these 3 files or 6 files? I can’t understand, also what i believe /tmp/fox/f 81 should give it as it is rather than /tmp/fox/f 81, so how cat is parsing them?

solved by ignoring or removing the single quotes in the cmdList[1:] no need of Echo in cat here, i guess same will be applied in double quotes too.

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.