代码问题-目标c-等待字符串值出现在字符串值中

发布于 2024-09-14 09:06:27 字数 1683 浏览 5 评论 0原文

task = [NSTask new];
[task setLaunchPath:@"/bin/sh"];
[task setArguments:[NSArray arrayWithObject:@"/applications/jarvis/brain/server.sh"]];
[task setCurrentDirectoryPath:@"/"];

NSPipe *outputPipe = [NSPipe pipe];
[task setStandardInput:[NSPipe pipe]];
[task setStandardOutput:outputPipe];

[task launch];

NSMutableString *outputString = [NSMutableString string];
while ([outputString rangeOfString:@"Jarvis>"].location == NSNotFound) {
    [outputString appendString:[[[NSString alloc] initWithData:[[outputPipe fileHandleForReading] readDataToEndOfFile] encoding:NSUTF8StringEncoding] autorelease]];
     }

NSArray* substrings = [outputString componentsSeparatedByString:@"Jarvis>"];
NSString* finalCharlieOutputNSTask = [substrings lastObject];
NSSpeechSynthesizer * syn = [[NSSpeechSynthesizer alloc] init];
[syn startSpeakingString:finalCharlieOutputNSTask]; 
self.charlieOutput.stringValue = finalCharlieOutputNSTask;

好的,这就是我的代码。它启动一个 SH 文件并读取输出。但是,我希望它等到“Jarvis>”在说出并打印结果之前出现在字符串中。但是,似乎使用 while 循环,我的代码就冻结在那里。如果没有它,它会读取启动 server.sh 文件的正常输出,但会读取整个内容。有什么想法为什么这行不通吗?

这是 Server.sh 文件:

echo Starting Jarvis Program D.
ALICE_HOME=.
SERVLET_LIB=lib/servlet.jar
ALICE_LIB=lib/aliceserver.jar
JS_LIB=lib/js.jar

# Set SQL_LIB to the location of your database driver.
SQL_LIB=lib/mysql_comp.jar

# These are for Jetty; you will want to change these if you are using a different http server.
 HTTP_SERVER_LIBS=lib/org.mortbay.jetty.jar

 PROGRAMD_CLASSPATH=$SERVLET_LIB:$ALICE_LIB:$JS_LIB:$SQL_LIB:$HTTP_SERVER_LIBS
 java -classpath $PROGRAMD_CLASSPATH -Xms64m -Xmx128m org.alicebot.server.net.AliceServer $1
task = [NSTask new];
[task setLaunchPath:@"/bin/sh"];
[task setArguments:[NSArray arrayWithObject:@"/applications/jarvis/brain/server.sh"]];
[task setCurrentDirectoryPath:@"/"];

NSPipe *outputPipe = [NSPipe pipe];
[task setStandardInput:[NSPipe pipe]];
[task setStandardOutput:outputPipe];

[task launch];

NSMutableString *outputString = [NSMutableString string];
while ([outputString rangeOfString:@"Jarvis>"].location == NSNotFound) {
    [outputString appendString:[[[NSString alloc] initWithData:[[outputPipe fileHandleForReading] readDataToEndOfFile] encoding:NSUTF8StringEncoding] autorelease]];
     }

NSArray* substrings = [outputString componentsSeparatedByString:@"Jarvis>"];
NSString* finalCharlieOutputNSTask = [substrings lastObject];
NSSpeechSynthesizer * syn = [[NSSpeechSynthesizer alloc] init];
[syn startSpeakingString:finalCharlieOutputNSTask]; 
self.charlieOutput.stringValue = finalCharlieOutputNSTask;

Ok, so that's my code. It launches an SH file and reads the output. BUT, I want it to wait until "Jarvis>" appears in the string before saying and printing the result. But, it seems like with the while loop, my code freezes there. Without it it reads the normal output of launching the server.sh file, but the whole thing. Any ideas why this doesn't work?

Here is the Server.sh file:

echo Starting Jarvis Program D.
ALICE_HOME=.
SERVLET_LIB=lib/servlet.jar
ALICE_LIB=lib/aliceserver.jar
JS_LIB=lib/js.jar

# Set SQL_LIB to the location of your database driver.
SQL_LIB=lib/mysql_comp.jar

# These are for Jetty; you will want to change these if you are using a different http server.
 HTTP_SERVER_LIBS=lib/org.mortbay.jetty.jar

 PROGRAMD_CLASSPATH=$SERVLET_LIB:$ALICE_LIB:$JS_LIB:$SQL_LIB:$HTTP_SERVER_LIBS
 java -classpath $PROGRAMD_CLASSPATH -Xms64m -Xmx128m org.alicebot.server.net.AliceServer $1

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

白况 2024-09-21 09:06:27

Elijah,将您的代码编辑为如下所示:

...
[task launch];

NSMutableString *outputString = [NSMutableString string];
while ([outputString rangeOfString:@"Jarvis>"].location == NSNotFound) {
    [outputString appendString:[[[NSString alloc] initWithData:[[outputPipe fileHandleForReading] readDataToEndOfFile] encoding:NSUTF8StringEncoding] autorelease];
}

if ([task isRunning]) {
    [task terminate];
}

NSArray *subStrings = [outputString componentsSeparatedByString:@"Jarvis>"];
...

循环中的此代码将连续从文件中读取输出数据并将其附加到当前输出,并在@“Jarvis>”时停止读取找到(它也会在找到@“Jarvis>”后终止任务,因此它不会永远运行)。

Elijah, edit your code to look like this:

...
[task launch];

NSMutableString *outputString = [NSMutableString string];
while ([outputString rangeOfString:@"Jarvis>"].location == NSNotFound) {
    [outputString appendString:[[[NSString alloc] initWithData:[[outputPipe fileHandleForReading] readDataToEndOfFile] encoding:NSUTF8StringEncoding] autorelease];
}

if ([task isRunning]) {
    [task terminate];
}

NSArray *subStrings = [outputString componentsSeparatedByString:@"Jarvis>"];
...

This code within the loop will successively read output data from your file and append it to the current output, and stop reading when @"Jarvis>" is found (it will also kill the task after a @"Jarvis>" is found, so it doesn't keep running forever).

洛阳烟雨空心柳 2024-09-21 09:06:27

您想将 readDataToEndOfFile 放入循环内。否则,它会读取一次数据,检查字符串是否存在,如果在第一次读取中没有找到它,则永远循环。

You want to put the readDataToEndOfFile inside the loop. Otherwise, it reads the data once, checks for existence of your string, then loops forever if it doesn't find it in that first reading.

扛刀软妹 2024-09-21 09:06:27

也许尝试按照文章中发布的代码行刷新 NSPipe:

“NSTasks、NSPipes 和读取时的死锁...”,

http://dev.notoptimal.net/2007/04/nstasks-nspipes-and-deadlocks-when.html

另一种方法可以测试NSTask 的使用NSUnbufferedIO。

您可以在 Don Yacktman 所著的《Cocoa 编程》一书中找到一些示例代码。

# http://www.cocoaprogramming.net
# http://www.cocoaprogramming.net/CocoaProgramming-20021010.tgz

open -e CocoaProgramming-20021010/Chapter\ 24/Animal/AnimalController.h \
        CocoaProgramming-20021010/Chapter\ 24/Animal/AnimalController.m \
        CocoaProgramming-20021010/Chapter\ 24/Calendar/CalendarController.m

# for yet another try with sample code using waitForDataInBackgroundAndNotify see:
# http://cocoawithlove.com/2009/05/invoking-other-processes-in-cocoa.html

open -e OpenFileKiller/NSTask+OneLineTasksWithOutput.m
# --> [standardOutputFile waitForDataInBackgroundAndNotify];

Maybe try flushing NSPipe along the lines of code published in the article:

"NSTasks, NSPipes, and deadlocks when reading...",

http://dev.notoptimal.net/2007/04/nstasks-nspipes-and-deadlocks-when.html

Yet another approach could test the use of NSTask & NSUnbufferedIO.

You will find some example code in the book "Cocoa Programming" by Don Yacktman.

# http://www.cocoaprogramming.net
# http://www.cocoaprogramming.net/CocoaProgramming-20021010.tgz

open -e CocoaProgramming-20021010/Chapter\ 24/Animal/AnimalController.h \
        CocoaProgramming-20021010/Chapter\ 24/Animal/AnimalController.m \
        CocoaProgramming-20021010/Chapter\ 24/Calendar/CalendarController.m

# for yet another try with sample code using waitForDataInBackgroundAndNotify see:
# http://cocoawithlove.com/2009/05/invoking-other-processes-in-cocoa.html

open -e OpenFileKiller/NSTask+OneLineTasksWithOutput.m
# --> [standardOutputFile waitForDataInBackgroundAndNotify];
梅窗月明清似水 2024-09-21 09:06:27

对于 NSTask & 的非阻塞 IO 代码NSFileManager 还可以查看 DOCtor 的源代码:

# http://www.stone.com/DOCtor/
# http://www.stone.com/DOCtor/DOCtor.tar.gz

open -e DOCTor/NSFileHandle_CFRNonBlockingIO.h \
        DOCTor/NSFileHandle_CFRNonBlockingIO.m \
        DOCTor/NSFileManager-Extensions.h \
        DOCTor/NSFileManager-Extensions.m

另请注意,如果 stdout 是管道而不是交互式终端 (tty),则许多命令行程序(内部)会阻止将其输出缓冲到 stdout。因此,某些命令行程序具有特殊选项来行缓冲其输出,而不管将输出发送到管道还是 tty。

tcpdump -l
grep --line-buffered
...

For non-blocking IO code for NSTask & NSFileManager also see the source code of DOCtor:

# http://www.stone.com/DOCtor/
# http://www.stone.com/DOCtor/DOCtor.tar.gz

open -e DOCTor/NSFileHandle_CFRNonBlockingIO.h \
        DOCTor/NSFileHandle_CFRNonBlockingIO.m \
        DOCTor/NSFileManager-Extensions.h \
        DOCTor/NSFileManager-Extensions.m

Also note that many command line programs (internally) block buffer their output to stdout if stdout is a pipe and not an interactive terminal (tty). For this reason some command line programs have special options to line-buffer their output regardless of sending output to a pipe or tty.

tcpdump -l
grep --line-buffered
...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文